<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="rss.xsl"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Palform Blog</title>
        <link>https://docs.palform.app/blog</link>
        <description>Palform Blog</description>
        <lastBuildDate>Thu, 28 Nov 2024 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[Struggling to get leads? Your lead gen forms might be to blame...]]></title>
            <link>https://docs.palform.app/blog/2024/11/28/lead-gen-tips</link>
            <guid>https://docs.palform.app/blog/2024/11/28/lead-gen-tips</guid>
            <pubDate>Thu, 28 Nov 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[We get it. You're using Google Forms to collect data from your leads and customers, but something just isn't right. Your conversion rates are low, the forms look unprofessional, and it's a pain to integrate with any other platforms. Leads inexplicably avoid engaging, and you're getting more desperate searching for answers.]]></description>
            <content:encoded><![CDATA[<p>We get it. You're using Google Forms to collect data from your leads and customers, but something just isn't right. Your <strong>conversion rates are low</strong>, the forms look <strong>unprofessional</strong>, and it's a <strong>pain to integrate</strong> with any other platforms. Leads inexplicably avoid engaging, and you're getting more <strong>desperate searching for answers</strong>.</p>
<p>But there's literally hundreds of competing form builders on the market, and the options are just super overwhelming. The costs of the high-quality alternatives are exorbitant which doesn't help when you're already struggling to make a profit.</p>
<p>Don't worry: I'm here to guide you through what makes an <strong>engaging, high-converting</strong> lead gen form that will actually make you money. These tips are all <strong>easy to implement</strong> and will <strong>rapidly improve your engagement rates</strong>.</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="1-keep-it-simple">1. Keep it simple<a href="https://docs.palform.app/blog/2024/11/28/lead-gen-tips#1-keep-it-simple" class="hash-link" aria-label="Direct link to 1. Keep it simple" title="Direct link to 1. Keep it simple" translate="no">​</a></h2>
<p>Take some time to consider where your user is in their journey.</p>
<p>They've just clicked your Instagram ad and its taken them to your form. They're maybe <em>slightly</em> curious about you, but filling in their data takes effort and time.</p>
<p>Remember, average consumer attention is <a href="https://krausgroupmarketing.com/marketing-strategy/average-consumer-attention-span-has-dropped-again-in-2022/" target="_blank" rel="noopener noreferrer" class="">8 seconds</a>. Think: can you fill your form in 8 seconds?</p>
<p>Although you may be running a B2B strategy, you're still marketing to human beings at the end of the day, so some careful engineering is crucial.</p>
<p>Some questions to ask:</p>
<ul>
<li class="">Do you really need your lead's full home address?</li>
<li class="">Do you need their phone number <em>and</em> email? Can you just make do with one?</li>
<li class="">Are you presenting all the questions at once? It might feel overwhelming.</li>
</ul>
<p>The simpler your form, the more likely users are to complete it all the way through. Scrape it down to its bare minimum, collecting only the information you genuinely need, and removing any surplus details.</p>
<p>This example collects all the data you need to do some basic research on the person and company, as well as a way to contact them. In 99% of cases, you really don't need more data than this!</p>
<div class="p-2 rounded-xl overflow-hidden border-2 border-solid bg-slate-50 dark:bg-slate-900 border-green-400 dark:border-green-900"><iframe src="https://dash.palform.app/fill/org_0GYDWW6VM4C0E/form_0J1BA3AK64ZK2?f=fat_0J1BA9XCP4QS7#ak=C63ECEF4B27E8B6D74F838FC9C7DDFA0BB9F447F" height="280" width="100%"></iframe></div><p class="mt-2 text-sm uppercase tracking-widest text-green-500">Good example</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="2-give-repeated-reassurance">2. Give repeated reassurance<a href="https://docs.palform.app/blog/2024/11/28/lead-gen-tips#2-give-repeated-reassurance" class="hash-link" aria-label="Direct link to 2. Give repeated reassurance" title="Direct link to 2. Give repeated reassurance" translate="no">​</a></h2>
<p>Modern-day consumers are increasingly worried about how their data is handled. Every new data point you're collecting will need a sort of "mental" justification for many people, which can be easy to forget when you're solely focussed on collecting as much data as possible.</p>
<p>It's important to be super clear about how you're handling their data and what security practices you'll be using. Not only to make leads feel comfortable, but also to ensure you're following data protection laws <a class="" href="https://docs.palform.app/blog/2024/09/07/google-forms-gdpr">such as the GDPR</a>.
Here's some simple things you can do:</p>
<ul>
<li class="">At the start of the form, <strong>include a link to your Privacy Policy</strong>. Not only is this legally required, it makes your business look super professional and convinces your users they're in comfortable hands.</li>
<li class="">Use an <strong>end-to-end encrypted form builder</strong>. The majority of form builders on the market such as Google Forms and Typeform don't fully encrypt response data. Users can feel creeped out by this, and it exposes you to serious data breaches. Try <a href="https://palform.app/" target="_blank" rel="noopener noreferrer" class="">Palform</a>, which offers unlimited responses for free, and security standards that outperform the entire industry.</li>
<li class="">Explain briefly <strong>why you need their contact details</strong>. If you'll be sending them a newsletter, make that clear! Most people will only be interested in talking to you directly, and reassuring them they won't receive any unwanted emails can increase their confidence.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="3-use-a-lead-magnet">3. Use a lead magnet<a href="https://docs.palform.app/blog/2024/11/28/lead-gen-tips#3-use-a-lead-magnet" class="hash-link" aria-label="Direct link to 3. Use a lead magnet" title="Direct link to 3. Use a lead magnet" translate="no">​</a></h2>
<p>There's nothing more exciting than getting free stuff.</p>
<p>Present an appetising offer from the get-go. This makes it clear your form is worth filling out, and it's possibly <em>the</em> best way to reduce dropoff. Customers will be willing to spend way more time providing their data if they know they're getting something in return.</p>
<p>Some examples include:</p>
<ul>
<li class=""><strong>Free trials</strong>: make sure these sound exclusive and exciting, for example by giving an offer that isn't normally advertised by your company.</li>
<li class=""><strong>Lifetime deals</strong>: offer a limited-time one-off price that gets users unlimited lifetime access to your normally subscription-based product. This is a much easier sell and often something that's just too good to miss.</li>
<li class=""><strong>Free consultations</strong>: offer a way to speak to a real human being. It's getting rarer to see genuine humans behind ever-growing mysterious SaaS companies, so standing out from the crowd can help you here.</li>
</ul>
<p>Or try offering a guide/resource that promises to solve common problems experienced by your target audience, like in this example form:</p>
<div class="p-2 rounded-xl overflow-hidden border-2 border-solid bg-slate-50 dark:bg-slate-900 border-green-400 dark:border-green-900"><iframe src="https://dash.palform.app/fill/org_0GYDWW6VM4C0E/form_0J1BFK17J4W7R?f=fat_0J1BFQ3FJ4XE9#ak=C63ECEF4B27E8B6D74F838FC9C7DDFA0BB9F447F" height="300" width="100%"></iframe></div><p class="mt-2 text-sm uppercase tracking-widest text-green-500">Good example</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="4-make-sure-your-design-stands-out">4. Make sure your design stands out<a href="https://docs.palform.app/blog/2024/11/28/lead-gen-tips#4-make-sure-your-design-stands-out" class="hash-link" aria-label="Direct link to 4. Make sure your design stands out" title="Direct link to 4. Make sure your design stands out" translate="no">​</a></h2>
<p>The worst mistake you can make is using ugly forms that look unprofessional. Google and Microsoft forms just scream "low effort" and convince your leads you're not taking them seriously.</p>
<p>Not to mention:</p>
<ul>
<li class="">your branding is basically <strong>completely non-existent</strong></li>
<li class="">it's on a <strong>random domain</strong> that's impossible to memorise</li>
<li class="">a megacorporation known for <a href="https://firewalltimes.com/google-data-breach-timeline/" target="_blank" rel="noopener noreferrer" class="">non-stop data breaches</a> gets <strong>front-row access to your data</strong></li>
<li class="">and so on...</li>
</ul>
<p>Use a form builder that gives you powerful customisation options: you want to be able to modify <strong>everything</strong>, from colours to images, and border rounding to font settings. <a href="https://palform.app/" target="_blank" rel="noopener noreferrer" class="">Palform</a> offers a sophisticated branding scheme editor that consistently applies your organisation's design to all your forms.</p>
<p>Take a look at this heavily-branded example:</p>
<div class="p-2 rounded-xl overflow-hidden border-2 border-solid bg-slate-50 dark:bg-slate-900 border-green-400 dark:border-green-900"><iframe src="https://dash.palform.app/fill/org_0GYDWW6VM4C0E/form_0J1JQR0VP4J03?f=fat_0J1JSVD1Y4ZWZ#ak=C63ECEF4B27E8B6D74F838FC9C7DDFA0BB9F447F" height="450" width="100%"></iframe></div><p class="mt-2 text-sm uppercase tracking-widest text-green-500">Good example</p>
<p>It conveys a sense of luxury and elegance that an unbranded form simply wouldn't. Add a logo and some more custom assets, and it's perfect!</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="5-handle-the-response-surge">5. Handle the response surge!<a href="https://docs.palform.app/blog/2024/11/28/lead-gen-tips#5-handle-the-response-surge" class="hash-link" aria-label="Direct link to 5. Handle the response surge!" title="Direct link to 5. Handle the response surge!" translate="no">​</a></h2>
<p>Now that you've made the perfect lead gen form, it's important to be prepared for the surge of response you'll inevitably receive.</p>
<p>But here's where the real obstacle comes in. <strong>Nearly all form builders have annoying response limits!</strong></p>
<p>Take Typeform as an example. On the <a href="https://www.typeform.com/pricing/" target="_blank" rel="noopener noreferrer" class="">free plan</a>, you're restricted to a mere <strong>10 responses per month</strong>. If you want more, you'll have to hand over at least £21 per month. And that still only gets you 100 responses.</p>
<p>The number of posts on X about Typeforms filling up and breaking down is constantly growing and quite sad to look at. There's nothing more unprofessional than your form just <strong>ceasing to work</strong> in the middle of the night and <strong>losing leads</strong> to it.</p>
<p>With <a href="https://palform.app/#pricing" target="_blank" rel="noopener noreferrer" class="">Palform</a> you get unlimited responses completely free of charge. In fact, all plans include unlimited responses. Your forms will just keep growing with you at no extra cost, so you can actually get some sleep! Feel free to post the submission link anywhere on the internet and stop worrying.</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="conclusion">Conclusion<a href="https://docs.palform.app/blog/2024/11/28/lead-gen-tips#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>Hopefully you've gained some good tips on how to level up your forms and optimise them for higher conversions. It's something that often takes hours of experimentation, and you'll probably fail a few times before you land on a winning design. The important thing is to <strong>keep iterating</strong> and getting feedback!</p>
<hr>
<p>This article was written by Pal Kerecsenyi, Founder of <a href="https://palform.app/" target="_blank" rel="noopener noreferrer" class="">Palform</a>. Sign up for free now and get unlimited responses with the world's most secure form builder.</p>
<p>Got any questions? Email <a href="mailto:hey@palform.app" target="_blank" rel="noopener noreferrer" class="">hey@palform.app</a> and we'll get an actual friendly human to help you.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[4 reasons why it's time to ditch Typeform]]></title>
            <link>https://docs.palform.app/blog/2024/10/26/ditch-typeform</link>
            <guid>https://docs.palform.app/blog/2024/10/26/ditch-typeform</guid>
            <pubDate>Sat, 26 Oct 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[A person fills in a paper form on a clipboard with a pen.]]></description>
            <content:encoded><![CDATA[<p><img decoding="async" loading="lazy" alt="A person fills in a paper form on a clipboard with a pen." src="https://docs.palform.app/assets/images/banner-0b3fb522b389cf4b963abbe4b406d81d.jpg" width="6000" height="4000" class="img_al4G"></p>
<p><a href="https://typeform.com/" target="_blank" rel="noopener noreferrer" class="">Typeform</a> is beloved by marketing teams the world over — and with good reason! Since its launch in 2014, it's revolutionised the way people collected data. Rather than just a bland series of boxes and buttons, forms were now brilliantly colourful full-featured experiences that end-users actually enjoyed filling out.</p>
<p>However, Typeform's rapid growth has introduced a range of problems for its users. The extreme pricing makes it an increasingly hard option to justify, and the complex web of new features and models greatly grows the learning curve over time.</p>
<p>Maybe it's time to look for a simpler, friendlier, more secure, and more affordable alternative. Read on to find out why.</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="1-unaffordable-pricing">1. Unaffordable pricing<a href="https://docs.palform.app/blog/2024/10/26/ditch-typeform#1-unaffordable-pricing" class="hash-link" aria-label="Direct link to 1. Unaffordable pricing" title="Direct link to 1. Unaffordable pricing" translate="no">​</a></h2>
<p>It's no secret that Typeform is the "luxury" option on the market. While not offering substantially more value than competitors, its pricing gives the appearance that it does something no other form builder can do.</p>
<p>The free plan, neatly hidden at the very bottom of <a href="https://www.typeform.com/pricing/" target="_blank" rel="noopener noreferrer" class="">their pricing page</a>, includes <strong>only 10 responses per month</strong>. Even an extremely simple student research project will easily exceed this number, making it nearly useless for anything other than tiny-scale demos.</p>
<p>From there, pricing just scales into oblivion:</p>
<ul>
<li class="">£21/month for 100 responses</li>
<li class="">£41/month for 1,000 responses</li>
<li class="">£66/month for 10,000 responses</li>
</ul>
<p>Even other variables like <strong>user count or file upload size</strong> get limited between plans. This makes forecasting really difficult and can easily end up costing you heavily. Once you're locked in, switching might be difficult.</p>
<p>In fact, some features are hidden behind a "Contact Sales" enterprise option, rendering some pricing options invisible and unpredictable.</p>
<p><a href="https://palform.app/" target="_blank" rel="noopener noreferrer" class="">Palform</a>, a leading competitor, offers unlimited responses even on the free plan. You only pay for advanced features like brand customisation or a custom subdomain. A simple flat fee makes it an easier option to buy with confidence and security. All pricing information is fully open, and there's no special features you need to sign a complex contract to access.</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="2-privacy-issues">2. Privacy issues<a href="https://docs.palform.app/blog/2024/10/26/ditch-typeform#2-privacy-issues" class="hash-link" aria-label="Direct link to 2. Privacy issues" title="Direct link to 2. Privacy issues" translate="no">​</a></h2>
<p>Typeform's main servers are hosted <a href="https://www.typeform.com/help/a/security-at-typeform-360029259552/#h_01FDEP4WZJNRTM5HDFY7KY793T" target="_blank" rel="noopener noreferrer" class="">in the US</a>, despite the company itself being based in Barcelona. While from a legal perspective this isn't a direct violation of the GDPR, many European users will be skeptical about their data going through such Barcelona. While from a legal perspective this isn't a direct violation of the GDPR, <strong>many European users will be skeptical</strong> about their data going through such seemingly unnecessary international transfers.</p>
<p><a href="https://www.statista.com/statistics/1122408/internet-users-worldwide-looking-better-ways-protect-privacy/" target="_blank" rel="noopener noreferrer" class="">Internet users want privacy</a> more than ever, and your company can gain increased engagement simply by choosing high-quality service providers that show a clear commitment to treating end-user data with respect and compliance.</p>
<p>Furthermore, while they wouldn't necessarily use it regularly, Typeform has access to <em>all</em> your response data. If they wanted to (or e.g. if they were required to by a court order), they could see any potentially confidential data submitted by your customers. While they employ at-rest and in-cloud encryption, this doesn't completely prevent certain members of their own staff (or a hacker posing as such) from accessing your data.</p>
<p>To be clear, this is the standard model used by the majority of cloud-based services. Despite this, <a href="https://www.statista.com/statistics/273550/data-breaches-recorded-in-the-united-states-by-number-of-breaches-and-records-exposed/" target="_blank" rel="noopener noreferrer" class="">the number of data breaches keeps growing year-on-year</a>. A <em>lot</em> of these breaches could be prevented by employing more secure full end-to-end encryption.</p>
<p>With new players in the field such as <a href="https://palform.app/" target="_blank" rel="noopener noreferrer" class="">Palform</a>, <a href="https://www.jotform.com/encrypted-forms/" target="_blank" rel="noopener noreferrer" class="">Jotform</a> (under certain settings), and <a href="https://blocksurvey.io/" target="_blank" rel="noopener noreferrer" class="">BlockSurvey</a> this means the data is <strong>fully encrypted</strong> between the end-user's browser and yours. Absolutely nobody, <strong>not even the form service themselves</strong> can see the responses.</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="3-over-complicated-new-features">3. Over-complicated new features<a href="https://docs.palform.app/blog/2024/10/26/ditch-typeform#3-over-complicated-new-features" class="hash-link" aria-label="Direct link to 3. Over-complicated new features" title="Direct link to 3. Over-complicated new features" translate="no">​</a></h2>
<p>Typeform is under constant development, and a host of new features have been added since 2014. These have increased flexibility, but arguably have also made the platform much more complex and hard to navigate, especially for new users.</p>
<p>New additions such as personalised video content, CRM data enrichment, and AI analysis may seem helpful. But do you really need them? They're likely to creep out your users, while also distracting Typeform from really perfecting their platform's core. Sometimes, less is more.</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="4-closed-source-code">4. Closed-source code<a href="https://docs.palform.app/blog/2024/10/26/ditch-typeform#4-closed-source-code" class="hash-link" aria-label="Direct link to 4. Closed-source code" title="Direct link to 4. Closed-source code" translate="no">​</a></h2>
<p>We get it, this is a technical one. But it really makes a big impact!</p>
<p>Typeform, like almost all competing form builders, is closed-source. You can't see the code behind the platform that handles all your trusted customer data and sensitive information. While this may seem trivial at first, consider the implications: you have <em>zero</em> insight into how that data gets handled. Maybe it gets sent to a wide range of third-party services you had no idea about. Or maybe there are serious security vulnerabilities. You simply can't tell.</p>
<p>Of course, open source code isn't inherently secure, despite popular belief. However, sharing the code implies that the company is so confident in its security that it'll allow anyone to inspect it. In fact, it'll even accept improvements and bug fixes from anyone who wants to contribute.</p>
<p>There's a whole host of other benefits to open source codebases, and it's absolutely something you should be considering when looking for a form builder. You can <a class="" href="https://docs.palform.app/blog/2024/09/02/open-source">read more</a> about <a href="https://palform.app/" target="_blank" rel="noopener noreferrer" class="">Palform</a>'s motivation for releasing its source code.</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="is-it-worth-my-time">Is it worth my time?<a href="https://docs.palform.app/blog/2024/10/26/ditch-typeform#is-it-worth-my-time" class="hash-link" aria-label="Direct link to Is it worth my time?" title="Direct link to Is it worth my time?" translate="no">​</a></h2>
<p>Switching away from Typeform isn't as hard as it seems. Most form builders offer a consistent and predictable set of features, and usually a consistent UI to go along with it. Setting up your branding and adding all your questions never takes more than a few minutes, and you could get great benefits by making a simple switch, including:</p>
<ul>
<li class="">Massively reducing your bills</li>
<li class="">Improving security and customer trust</li>
<li class="">Experiencing a simpler, less disorientating set of features</li>
</ul>
<p>If you need more inspiration for which platform to choose, <a class="" href="https://docs.palform.app/blog/2024/09/03/form-builders-2024">read our article comparing 7 of the best</a>.</p>
<hr>
<blockquote>
<p>Thanks for reading! This article was written by Pal Kerecsenyi, founder of Palform. If you have any questions, please contact <a href="mailto:hey@palform.app" target="_blank" rel="noopener noreferrer" class="">hey@palform.app</a>.</p>
</blockquote>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Encrypted surveys: Palform's security practices]]></title>
            <link>https://docs.palform.app/blog/2024/09/08/security</link>
            <guid>https://docs.palform.app/blog/2024/09/08/security</guid>
            <pubDate>Sun, 08 Sep 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Palform's aim is to do for forms what Proton, Tuta, and others did for emails: make them encrypted, privacy-respecting, and open. And most of all, to be so simple that anyone can use it, without an understanding of the technology.]]></description>
            <content:encoded><![CDATA[<p><a href="https://palform.app/" target="_blank" rel="noopener noreferrer" class="">Palform</a>'s aim is to do for forms what <a href="https://proton.me/" target="_blank" rel="noopener noreferrer" class="">Proton</a>, <a href="https://tuta.com/" target="_blank" rel="noopener noreferrer" class="">Tuta</a>, and others did for emails: make them <strong>encrypted, privacy-respecting, and open</strong>. And most of all, to be so simple that anyone can use it, without an understanding of the technology.</p>
<p>It's an ambitious project, and I'm well aware that transparency is critical. I've implemented a range of security practices to ensure Palform can deliver on these claims. However, there's also a range of compromises I've had to make to ensure a good balance between usability and security.</p>
<p>This post aims to lay out clearly what Palform protects you against and how, and also what it <em>doesn't</em> protect you against.</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="security-practices">Security practices<a href="https://docs.palform.app/blog/2024/09/08/security#security-practices" class="hash-link" aria-label="Direct link to Security practices" title="Direct link to Security practices" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar__jMZ" id="end-to-end-encrypted-responses">End-to-end encrypted responses<a href="https://docs.palform.app/blog/2024/09/08/security#end-to-end-encrypted-responses" class="hash-link" aria-label="Direct link to End-to-end encrypted responses" title="Direct link to End-to-end encrypted responses" translate="no">​</a></h3>
<p>Palform end-to-end encrypts all responses to forms, meaning no intermediaries (Palform, our server providers, infrastructure operators, etc.) are able to see them. This is always on (unlike e.g. <a href="https://www.jotform.com/help/344-encrypted-forms-and-how-to-use-them/" target="_blank" rel="noopener noreferrer" class="">Jotform</a> where it's an opt-in feature) and cannot be turned off. This helps reassure users that when they see a Palform, it will be encrypted.</p>
<p>Correctly implemented encryption is one of the most powerful methods of safeguarding data. It's something no major form builders provide by default.</p>
<p>Palform uses OpenPGP through the <a href="https://sequoia-pgp.org/" target="_blank" rel="noopener noreferrer" class="">Sequoia PGP</a> library (in Rust). Compared to other implementations, this is written in a memory-safe language (automatically eliminating whole categories of vulnerabilities) while still being maintained very actively.</p>
<details class="details_yUPi alert alert--info details_uP_l" data-collapsed="true"><summary>How does your encryption work?</summary><div><div class="collapsibleContent_cMY2"><ul>
<li class="">Unlike other E2EE platforms, keys are <em>not</em> linked to user passwords. Instead, we create a random OpenPGP certificate for you in your browser and save it in long-term browser storage.<!-- -->
<ul>
<li class="">Where possible, we instruct your browser to never delete this data, even when it's tight on space.</li>
</ul>
</li>
<li class="">We generate a random passphrase made of a series of English words, and upload your full certificate to the server, encrypted with this passphrase.</li>
<li class="">Separately, the public component of the certificate is uploaded to the server unencrypted.</li>
<li class="">Users can be in teams, and each form belongs to a team. Multiple users need to see the responses to a form.</li>
<li class="">When the form is being filled, the server sends the public keys of all users in the team the form belongs to, and the client encrypts with these.</li>
</ul><p>You can read more <a class="" href="https://docs.palform.app/keys/technical">details in our documentation</a>.</p></div></div></details>
<details class="details_yUPi alert alert--info details_uP_l" data-collapsed="true"><summary>Do keys expire?</summary><div><div class="collapsibleContent_cMY2"><p>By default, we create non-expiring keys (for technical reasons, they actually expire in 100+ years). You can manually override the expiration date if you'd like.</p><p>We keep your expired keys indefinitely to let you decrypt responses made with them. New responses are only made to in-date keys. If you have none, new responses will be refused with a user-facing error message.</p></div></div></details>
<details class="details_yUPi alert alert--info details_uP_l" data-collapsed="true"><summary>I thought OpenPGP was dead?</summary><div><div class="collapsibleContent_cMY2"><p>Firstly, it's not. While adoption has been very limited for personal users, services with Proton Mail bundle it in an online interface where most people don't even know they're using it. As a result, it's actually deployed very very widely.</p><p>Secondly, it's a highly-trusted standard with an enormous community behind it, loads of documentation, first-class support in most languages, etc. Many users already use some form of OpenPGP and have existing keys they might want to use (you can import your own keys on Palform!), as well as an overall trust in its highly-proven ability to secure crucial data.</p><p>I don't want Palform to be a walled garden, and relying on something portable is a good way of ensuring that.</p><p>Also, Palform doesn't implement all features of OpenPGP, just the encryption. At the moment, it doesn't use signing as it doesn't really apply anywhere. The code implementation of the algorithms is intentionally extremely simple, relying only on the most simple highly-maintained functions of OpenPGP.</p></div></div></details>
<h3 class="anchor anchorTargetStickyNavbar__jMZ" id="open-source-code-base">Open source code base<a href="https://docs.palform.app/blog/2024/09/08/security#open-source-code-base" class="hash-link" aria-label="Direct link to Open source code base" title="Direct link to Open source code base" translate="no">​</a></h3>
<p>The entirety of Palform is <a href="https://github.com/palform/palform" target="_blank" rel="noopener noreferrer" class="">open source</a>, including the complete backend/frontend, the landing page, and even this blog post. I develop it fully in public, with no "hidden" code.</p>
<p>I know, <a href="https://www.privacyguides.org/en/basics/common-misconceptions/#open-source-software-is-always-secure-or-proprietary-software-is-more-secure" target="_blank" rel="noopener noreferrer" class="">it's not guaranteed secure just because it's open source</a>.</p>
<p>However, it's a step in the right direction. As I mentioned in <a class="" href="https://docs.palform.app/blog/2024/09/02/open-source">a previous post</a>, the client-side part of Palform performs a lot of encryption work in opaque binary WASM files (primarily for performance reasons). Having to murkily reverse engineer these would massively hinder users' confidence in the cryptography being applied correctly.</p>
<p>Having a public changelog also increases accountability and transparency into everything we do.</p>
<p>I'm also working on a self-hosted version, which I'll be posting updates on soon!</p>
<h3 class="anchor anchorTargetStickyNavbar__jMZ" id="third-party-providers">Third-party providers<a href="https://docs.palform.app/blog/2024/09/08/security#third-party-providers" class="hash-link" aria-label="Direct link to Third-party providers" title="Direct link to Third-party providers" translate="no">​</a></h3>
<p>There's certain elements of Palform that I can't reinvent from scratch. Right now, it uses third-party services for these components:</p>
<ul>
<li class=""><strong>Email notifications</strong> (<a href="https://www.mailgun.com/" target="_blank" rel="noopener noreferrer" class="">Mailgun</a>)<!-- -->
<ul>
<li class="">Your name and email address are passed to Mailgun, as well as the names of your forms when there's a response.</li>
<li class="">We never pass encrypted or plaintext response data to Mailgun</li>
</ul>
</li>
<li class=""><strong>Captcha</strong> (<a href="https://www.cloudflare.com/en-gb/products/turnstile/" target="_blank" rel="noopener noreferrer" class="">Cloudflare Turnstile</a>)<!-- -->
<ul>
<li class="">This is more private and less annoying than e.g. Google reCAPTCHA.</li>
<li class="">It's only loaded on pages where it's needed. By default it's not loaded on form fill pages, unless the form captcha feature is enabled.</li>
</ul>
</li>
<li class=""><strong>Analytics</strong> (<a href="https://plausible.io/" target="_blank" rel="noopener noreferrer" class="">Plausible Analytics</a>)<!-- -->
<ul>
<li class="">This is only loaded on the landing page and blog/docs pages. It does not collect any personally identifiable information.</li>
</ul>
</li>
<li class=""><strong>Payments</strong> (<a href="https://stripe.com/" target="_blank" rel="noopener noreferrer" class="">Stripe</a>)</li>
<li class=""><strong>Server and database hosting</strong> (<a href="https://www.scaleway.com/en/" target="_blank" rel="noopener noreferrer" class="">Scaleway</a>)</li>
</ul>
<p>Other than this, everything is built into the codebase. Reducing dependence on third-parties helps the open source nature of Palform and will make it easier to set up self-hosting.</p>
<p>No plaintext response data is ever passed to any third-parties.</p>
<p>We don't track any of your personal info for advertising purposes, and we don't operate any ads on our websites.</p>
<h3 class="anchor anchorTargetStickyNavbar__jMZ" id="data-location">Data location<a href="https://docs.palform.app/blog/2024/09/08/security#data-location" class="hash-link" aria-label="Direct link to Data location" title="Direct link to Data location" translate="no">​</a></h3>
<p>All data is stored and hosted in the EU on Scaleway's servers, and so is subject to the strict privacy regulations of the GDPR.</p>
<p>Palform is a company is based in the UK, and is subject to the Data Protection Act, which is currently very similar to the GDPR.</p>
<p>Our servers and databases only ever store encrypted response data. Plaintext responses never leave browsers.</p>
<h3 class="anchor anchorTargetStickyNavbar__jMZ" id="data-minimisation">Data minimisation<a href="https://docs.palform.app/blog/2024/09/08/security#data-minimisation" class="hash-link" aria-label="Direct link to Data minimisation" title="Direct link to Data minimisation" translate="no">​</a></h3>
<p>As required by law, we only collect the bare minimum data we need to operate. We don't collect any additional data on your form responses either (e.g. IP addresses or other analytics). All we can tell is how many responses your forms had, and when they happened.</p>
<h3 class="anchor anchorTargetStickyNavbar__jMZ" id="backups">Backups<a href="https://docs.palform.app/blog/2024/09/08/security#backups" class="hash-link" aria-label="Direct link to Backups" title="Direct link to Backups" translate="no">​</a></h3>
<p>Our database is automatically backed up every day, allowing us to quickly recover from corruption and data loss events. This helps us avoid losing your encrypted response data.</p>
<h3 class="anchor anchorTargetStickyNavbar__jMZ" id="authentication--authorisation">Authentication &amp; authorisation<a href="https://docs.palform.app/blog/2024/09/08/security#authentication--authorisation" class="hash-link" aria-label="Direct link to Authentication &amp; authorisation" title="Direct link to Authentication &amp; authorisation" translate="no">​</a></h3>
<p>You can use either email/password or OpenID Connect (on higher plans) to sign into Palform. We store passwords hashed with the industry-recommended Argon2 algorithms, and never in plaintext.</p>
<p>We support two-factor authentication with TOTP, and as a Yubikey user myself, I plan on adding security key support soon.</p>
<p>Authorisation is managed in a tiered system of organisations and teams. By default, new users in your org are added to your "default" team, with read-only permissions. You can customise this and set read, write, or admin permissions. Certain assets, like images and branding configurations, also belong to a team, and can be applied to all forms within that team.</p>
<p>This system means larger organisations also feel comfortable within Palform. They can even set up rules to automatically assign users into teams with givern permissions based on a response from their OIDC server.</p>
<h3 class="anchor anchorTargetStickyNavbar__jMZ" id="audit-logs">Audit logs<a href="https://docs.palform.app/blog/2024/09/08/security#audit-logs" class="hash-link" aria-label="Direct link to Audit logs" title="Direct link to Audit logs" translate="no">​</a></h3>
<p>Larger organisations using Palform can make use of audit logs to track events that occur in their organisation. This is not intrusive of employee's actions, as it doesn't track reads, only writes.</p>
<p>Any significant events, such as configuration changes or form response deletions, are clearly shown in the logs with associated metadata.</p>
<h3 class="anchor anchorTargetStickyNavbar__jMZ" id="other-helpful-features">Other helpful features<a href="https://docs.palform.app/blog/2024/09/08/security#other-helpful-features" class="hash-link" aria-label="Direct link to Other helpful features" title="Direct link to Other helpful features" translate="no">​</a></h3>
<p>I've tried to add features that help users improve their security practices and GDPR compliance:</p>
<ul>
<li class="">Auto-delete form responses within a certain number of days to comply with data retention limits</li>
<li class="">Force include a Privacy Policy link in all forms in a team</li>
<li class="">You own your data: responses can be exported in multiple formats whenever you want</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="limitations">Limitations<a href="https://docs.palform.app/blog/2024/09/08/security#limitations" class="hash-link" aria-label="Direct link to Limitations" title="Direct link to Limitations" translate="no">​</a></h2>
<p>Nothing is perfect, and it's very important to understand what Palform can't proctect you against.</p>
<p>Here are some known limitations:</p>
<ul>
<li class="">
<p><strong>Supply chain attacks</strong>: while we follow modern standards to prevent them (e.g. transparent CI builds, pushing containers straight to Scaleway, etc), they're a category of attacks that are essentially impossible to completely eliminate.</p>
<ul>
<li class="">For example, if someone compromised Palform's servers, they could send false public keys for an organisation, or serve up fake JavaScript on the frontend that steals encryption keys. This is the case for many end-to-end encrypted applications.</li>
</ul>
</li>
<li class="">
<p><strong>Backend validation</strong>: our backend is unable to validate your form responses, because it can't see them. You have to trust our client-side validation, which can technically be overcome. Therefore, it's important to not rely 100% on Palform's validation rules.</p>
</li>
<li class="">
<p><strong>Metadata</strong>: by the nature of OpenPGP, the key IDs of users are included in the encrypted responses. This might make it possible to tell which organisation/team/user a response can be read by. Also, the time of submission and the access token used are stored unencrypted.</p>
</li>
<li class="">
<p><strong>Non-response data</strong>: questions, form details, administrative users, etc. all have their details stored unencrypted in our database.</p>
</li>
<li class="">
<p><strong>You still have to comply with GDPR</strong> and any other privacy regulations. We don't magically do that for you, but we try to publish tools that help.</p>
</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="reporting-issues">Reporting issues<a href="https://docs.palform.app/blog/2024/09/08/security#reporting-issues" class="hash-link" aria-label="Direct link to Reporting issues" title="Direct link to Reporting issues" translate="no">​</a></h2>
<p>We're currently too small to operate a paid bug bounty program. However, we would still really appreciate responsible disclosures of any potential security issues you find in our systems, no matter how big or small.</p>
<p>These can be related either to our production websites (*.palform.app) or our code repository (<a href="https://github.com/palform/palform" target="_blank" rel="noopener noreferrer" class="">https://github.com/palform/palform</a>).</p>
<p>If you would like to report a problem, please email our <a class="" href="https://docs.palform.app/#encrypted-email">secure email address</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="questions-and-concerns">Questions and concerns<a href="https://docs.palform.app/blog/2024/09/08/security#questions-and-concerns" class="hash-link" aria-label="Direct link to Questions and concerns" title="Direct link to Questions and concerns" translate="no">​</a></h2>
<p>If you have any questions about our security practices, please <a class="" href="https://docs.palform.app/">contact us</a> and we'll be happy to help!</p>
<hr>
<blockquote>
<p>Thanks for reading! New here? Try out <a href="https://palform.app/" target="_blank" rel="noopener noreferrer" class="">Palform</a> online with unlimited responses free of charge.</p>
</blockquote>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Complying with GDPR as a Google Forms user is pretty hard]]></title>
            <link>https://docs.palform.app/blog/2024/09/07/google-forms-gdpr</link>
            <guid>https://docs.palform.app/blog/2024/09/07/google-forms-gdpr</guid>
            <pubDate>Sat, 07 Sep 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[I'm Pal, the founder of Palform. It's a free Google Forms alternative that reduces some of the pains and sorrows I'm about to detail in this post. And it doesn't cost anything.]]></description>
            <content:encoded><![CDATA[<p>I'm Pal, the founder of <a href="https://palform.app/" target="_blank" rel="noopener noreferrer" class="">Palform</a>. It's a free Google Forms alternative that reduces some of the pains and sorrows I'm about to detail in this post. And it <a href="https://palform.app/#pricing" target="_blank" rel="noopener noreferrer" class="">doesn't cost anything</a>.</p>
<div class="theme-admonition theme-admonition-warning admonition__oF4 alert alert--warning"><div class="admonitionHeading_xfBx"><span class="admonitionIcon_MkaD"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>warning</div><div class="admonitionContent_FPB_"><p>I'm by no means a GDPR expert, and this post is not legal advice. I've tried my best to research everything and provide evidence, but if I've made a mistake please email <a href="mailto:pal@palform.app" target="_blank" rel="noopener noreferrer" class="">pal@palform.app</a>.</p></div></div>
<hr>
<p>If you're a business based <em>anywhere in the world</em> and you're processing the personal data of citizens of the UK, EU, or EEA, you're required to comply with the famous <a href="https://gdpr.algolia.com/" target="_blank" rel="noopener noreferrer" class="">GDPR</a>.</p>
<blockquote>
<p>Example: Random Co. is a company based in California. They have a website with Google Analytics, meaning they're collecting personal information about users automatically. The website handles the personal information of EU users. Therefore, Random Co. must comply with the GDPR.</p>
</blockquote>
<p>This goes for Google Forms, too. If you have any EU/EEA/UK citizens filling in your form, you <em>must</em> comply.</p>
<p>So how do you do it?</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="requirements-for-compliance">Requirements for compliance<a href="https://docs.palform.app/blog/2024/09/07/google-forms-gdpr#requirements-for-compliance" class="hash-link" aria-label="Direct link to Requirements for compliance" title="Direct link to Requirements for compliance" translate="no">​</a></h2>
<p>I won't detail how to comply with the GDPR. That's a whole profession.</p>
<p>Two important requirements are:</p>
<ul>
<li class="">
<p><strong><a href="https://gdpr.algolia.com/gdpr-article-12" target="_blank" rel="noopener noreferrer" class="">Transparency</a></strong>. You need to provide a Privacy Policy or similar document, that details exactly how you process personal information, safeguards for protection, and the rights your users have.</p>
</li>
<li class="">
<p><strong><a href="https://gdpr.algolia.com/gdpr-article-44" target="_blank" rel="noopener noreferrer" class="">Data location</a></strong>. Transferring the data of EU/UK citizens outside of the EU/UK (e.g. into US data centers) can involve additional complexity. For example, transferring data to US companies is usually done by participating in the <a href="https://www.dataprivacyframework.gov/key-requirements" target="_blank" rel="noopener noreferrer" class="">Data Privacy Framework</a>, which comes with several requirements. It's often easier to just keep data in the EU, unless you're a large corporation with specific requirements.</p>
</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="can-i-fulfill-these-requirements-with-google-forms">Can I fulfill these requirements with Google Forms?<a href="https://docs.palform.app/blog/2024/09/07/google-forms-gdpr#can-i-fulfill-these-requirements-with-google-forms" class="hash-link" aria-label="Direct link to Can I fulfill these requirements with Google Forms?" title="Direct link to Can I fulfill these requirements with Google Forms?" translate="no">​</a></h2>
<p>Yes! It is possible to use Google Forms in compliance with the GDPR, but there are additional steps you need to take.</p>
<h3 class="anchor anchorTargetStickyNavbar__jMZ" id="transparency">Transparency<a href="https://docs.palform.app/blog/2024/09/07/google-forms-gdpr#transparency" class="hash-link" aria-label="Direct link to Transparency" title="Direct link to Transparency" translate="no">​</a></h3>
<p>Google Forms, by default, does not provide a way to display your organisation's Privacy Policy in forms you create. It's up to you to ensure <em>every single</em> form created by anyone has a dedicated field linking to your data handling practices.</p>
<p>Google was <a href="https://www.bbc.com/news/technology-46944696" target="_blank" rel="noopener noreferrer" class="">fined €50m in 2019</a> for failing to provide the GDPR-mandated information, although in relation to Google Ads, not Forms. My point is, there are actual fines for failing to provide the correct information.</p>
<h3 class="anchor anchorTargetStickyNavbar__jMZ" id="data-location">Data location<a href="https://docs.palform.app/blog/2024/09/07/google-forms-gdpr#data-location" class="hash-link" aria-label="Direct link to Data location" title="Direct link to Data location" translate="no">​</a></h3>
<p>You can configure the location of your data <strong>only if you're subscribed to Google Workspace Business Standard</strong> or higher. <a href="https://support.google.com/a/answer/14310028?hl=en" target="_blank" rel="noopener noreferrer" class="">Here's how to do it</a>.</p>
<p>If you're not using Google Forms within a Workspace account (i.e. just through a personal Google account), <strong>setting the location is not possible</strong>.</p>
<p>If your location is not set, <strong>your data is likely to be stored in the US</strong>. You don't really get much control.</p>
<p>Legally, this is not usually a problem, as Google is certified under the Data Privacy Framework, and so is a valid company to use as a data processor. However, many EU users might have concerns about transferring their data outside the EU, which could decrease their trust in your forms.</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="other-problems">Other problems<a href="https://docs.palform.app/blog/2024/09/07/google-forms-gdpr#other-problems" class="hash-link" aria-label="Direct link to Other problems" title="Direct link to Other problems" translate="no">​</a></h2>
<p><strong>Sharing your forms</strong> with collaborators can introduce complexity. It's easy to get a setting wrong and accidentally allow collaborators to re-share the form with more people, revealing the responses to people outside your organisation you shouldn't be able to see it.</p>
<p>You'll also need to ensure you're complying in terms of the <strong>data you're collecting</strong>. As with any data collection tool, you need to avoid collecting excessive data, and make special provisions for sensitive categories of personal information, such as medical records (including seemingly simple questions like "Do you have any dietary requirements?"). Of course, this goes for all form builders.</p>
<p>Finally, there's the question of <strong>user trust</strong>. Google has previously <a href="https://www.bbc.com/news/technology-63635380" target="_blank" rel="noopener noreferrer" class="">misled users</a> about their practices (this was not in relation to Forms, though). The majority of consumers worldwide are "<a href="https://iapp.org/resources/article/privacy-and-consumer-trust-summary/" target="_blank" rel="noopener noreferrer" class="">somewhat or very concerned</a>" about their privacy, and Google is arguably one of the reasons why.</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="making-compliance-a-little-easier">Making compliance a little easier<a href="https://docs.palform.app/blog/2024/09/07/google-forms-gdpr#making-compliance-a-little-easier" class="hash-link" aria-label="Direct link to Making compliance a little easier" title="Direct link to Making compliance a little easier" translate="no">​</a></h2>
<p>Here at <a href="https://palform.app/" target="_blank" rel="noopener noreferrer" class="">Palform</a>, we've built a privacy-focussed alternative to Google Forms. It aims to make GDPR compliance easier and increase customer trust. It's just as easy to use and it's completely free, too.</p>
<p>Here's how it helps:</p>
<ul>
<li class="">
<p>You can create <strong>organisation-wide privacy policies</strong> that automatically appear on all forms. This avoids costly mistakes and standardises the way you distribute information.</p>
</li>
<li class="">
<p><strong>All data is stored exclusively in the EU</strong> in secure databases. Plus, your responses are <strong>end-to-end encrypted</strong>, massively reducing the possibility and impact of data breaches, and helping you sleep better.</p>
</li>
<li class="">
<p>You can view and manage your form sharing centrally, and responses cannot be shared outside of your organisation by default. Plus, each viewer has their own key, so you get guaranteed knowledge of who can access each individual response.</p>
</li>
</ul>
<p>Of course, it's still important to comply with the GDPR in terms of the data you're collecting and the information you're providing. Palform is not a magic solution to all your problems, but it's here to help.</p>
<p>There's also other nifty features, like the customisable design tools and built-in analytical reports. All-in-all, it has all the benefits of Google Forms (and more), but without many of the drawbacks.</p>
<p><a href="https://palform.app/" target="_blank" rel="noopener noreferrer" class="">Give it a try</a> and see what you think!</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Do I need to pay the ICO fee? Check now to find out.]]></title>
            <link>https://docs.palform.app/blog/2024/09/06/ico-fee</link>
            <guid>https://docs.palform.app/blog/2024/09/06/ico-fee</guid>
            <pubDate>Fri, 06 Sep 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[The ICO fee must be paid by all organisations and sole traders who process personal information, unless they are exempt.]]></description>
            <content:encoded><![CDATA[<p>The ICO fee must be paid by all organisations and sole traders who process personal information, unless they are exempt.</p>
<p>Paying the data protection fee is important because it funds the ICO’s work providing advice and guidance about how to comply with the law – such as their online guidance, their telephone helpline, and their digital toolkits.</p>
<p>Fines for an overdue payment can range between £400 and £4,000, so paying the fee on time is really important!</p>
<div class="theme-admonition theme-admonition-warning admonition__oF4 alert alert--warning"><div class="admonitionHeading_xfBx"><span class="admonitionIcon_MkaD"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>warning</div><div class="admonitionContent_FPB_"><p><strong>Are you a non-UK business with some customers in the UK?</strong> You still need to comply with UK and EU data protection laws, and you probably need to pay the UK data protection fee.</p><p>Just because you're not based in the UK doesn't necessarily exempt you from UK laws and fees.</p></div></div>
<hr>
<p>Use our form below to figure out whether you need to pay a fee, and if so, then how much. You can also <a href="https://pf.palform.app/ico" target="_blank" rel="noopener noreferrer" class="">open the form in a new tab</a>.</p>
<iframe src="https://dash.palform.app/fill/org_0GYDWW6VM4C0E/form_0H6H32YZ1X72E?f=fat_0H6H38WWNX8RD" height="900px" width="800px"></iframe>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How type-safe scalable database IDs reduce bugs at Palform]]></title>
            <link>https://docs.palform.app/blog/2024/09/04/tsids</link>
            <guid>https://docs.palform.app/blog/2024/09/04/tsids</guid>
            <pubDate>Wed, 04 Sep 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[A datacentre with a row of disks. Green lights flashing.]]></description>
            <content:encoded><![CDATA[<p><img decoding="async" loading="lazy" alt="A datacentre with a row of disks. Green lights flashing." src="https://docs.palform.app/assets/images/banner-2e904a60b98b922a72b48c97e46944cc.jpg" width="6016" height="4016" class="img_al4G"></p>
<p>Database IDs are one of those things you really don't want to think about. It feels like they should just "work". Why are there different types of IDs?? Why can't I just use an auto-incrementing number? The real world is just so annoying.</p>
<p>In this article, I'll explain why UUIDs look like the cool solution to all our problems (but actually aren't), and demonstrate a simple but powerful system I used at Palform to vastly improve the database experience.</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="the-problems-with-uuids">The problems with UUIDs<a href="https://docs.palform.app/blog/2024/09/04/tsids#the-problems-with-uuids" class="hash-link" aria-label="Direct link to The problems with UUIDs" title="Direct link to The problems with UUIDs" translate="no">​</a></h2>
<p>Nowadays, UUIDs are often the go-to for the majority of developers. Essentially all major databases, ORMs, clients, and SDKs have built-in or high-quality 3rd-party support for them.</p>
<p>Yes they're slightly more difficult to generate, but you don't have to write code for that anymore!</p>
<p>With 128 bits of data, it's practically impossible to ever get a collision so you're safe from that too.</p>
<p>Around the internet, there are <a href="https://blog.boot.dev/clean-code/what-are-uuids-and-should-you-use-them/" target="_blank" rel="noopener noreferrer" class="">several</a> <a href="https://www.howtogeek.com/devops/what-are-uuids-and-why-are-they-useful/" target="_blank" rel="noopener noreferrer" class="">blog</a> <a href="https://www.uniqueids.org/en/what-is-uuid" target="_blank" rel="noopener noreferrer" class="">posts</a> advocating for their use over sequential IDs. And it's true: it's probably nearly always the better choice between the two. It hides the number of records you have and prevents automated enumeration, while not impacting performance <em>too</em> much in smaller databases.</p>
<p>But with <a href="https://palform.app/" target="_blank" rel="noopener noreferrer" class="">Palform</a>, my aim was to handle hundreds of thousands of form responses smoothly and lag-free. "Good enough" won't do, so we need a better solution.</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="enter-tsids">Enter TSIDs<a href="https://docs.palform.app/blog/2024/09/04/tsids#enter-tsids" class="hash-link" aria-label="Direct link to Enter TSIDs" title="Direct link to Enter TSIDs" translate="no">​</a></h2>
<p>Already gaining traction between developers, TSIDs <a href="https://www.foxhound.systems/blog/time-sorted-unique-identifiers/" target="_blank" rel="noopener noreferrer" class="">strike a balance</a> between incremental IDs and UUIDs. They're more space-efficient than the latter, while having the same time-sortable property of the former (although it's not fully guaranteed).</p>
<p>I won't write about the details of how they work here, as other posts have already done a much better job than I could.</p>
<p>They can be a bit of a pain with distributed systems as they require a node ID, which is not always easy to obtain in a definitely unique way. However, Palform is not really a distributed system.</p>
<p>Support is also much weaker than UUIDs, but that's also fine: luckily, Rust has an <a href="https://crates.io/crates/tsid" target="_blank" rel="noopener noreferrer" class="">excellent crate for it</a> which is really all I needed.</p>
<p>UUIDs are serialised in a <a href="https://www.rfc-editor.org/rfc/rfc9562.html#name-uuid-format" target="_blank" rel="noopener noreferrer" class="">highly standardised way</a>. They're so widespread that most developers can glance at the random-looking data and immediately tell it's a UUID. Just look at it:</p>
<div class="language-text codeBlockContainer_HeaP theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_M4gx"><pre tabindex="0" class="prism-code language-text codeBlock_NXtJ thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_QAHD"><div class="token-line" style="color:#393A34"><span class="token plain">de6fc6ac-2c80-48ce-9b48-f9793a0b8c71</span><br></div></code></pre></div></div>
<p>Mmmm beautiful.</p>
<p>TSIDs are 64 bit integers. They're usually serialised into a 13 character base-32 URL-safe string. That's much shorter and arguably more readable than a UUID:</p>
<div class="language-text codeBlockContainer_HeaP theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_M4gx"><pre tabindex="0" class="prism-code language-text codeBlock_NXtJ thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_QAHD"><div class="token-line" style="color:#393A34"><span class="token plain">0GYDWW6VM4C0E</span><br></div></code></pre></div></div>
<p>Even nicer.</p>
<p>So I made the decision: Palform would use TSIDs. But how to implement them?</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="seaorm-support">SeaORM support<a href="https://docs.palform.app/blog/2024/09/04/tsids#seaorm-support" class="hash-link" aria-label="Direct link to SeaORM support" title="Direct link to SeaORM support" translate="no">​</a></h2>
<p>Palform uses the excellent <a href="https://www.sea-ql.org/SeaORM/" target="_blank" rel="noopener noreferrer" class="">SeaORM</a> to manage database records on the backend. It has support for Postgres' built-in <code>uuid</code> type, but understandably no support for the relatively new TSID.</p>
<p>SeaORM requires declaring Rust entities (basically a struct) for each of your tables. This then makes it easy to write very Rust-idiomatic and satisfying database queries. Here's what an entity looks like when using UUIDs:</p>
<div class="language-rust codeBlockContainer_HeaP theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_M4gx"><pre tabindex="0" class="prism-code language-rust codeBlock_NXtJ thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_QAHD"><div class="token-line" style="color:#393A34"><span class="token attribute attr-name" style="color:#00a4db">#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token attribute attr-name" style="color:#00a4db">#[sea_orm(table_name = </span><span class="token attribute attr-name string" style="color:#e3116c">"auth_token"</span><span class="token attribute attr-name" style="color:#00a4db">)]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token type-definition class-name">Model</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> hash</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">String</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> created_at</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">DateTime</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> expires_at</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">DateTime</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token attribute attr-name" style="color:#00a4db">#[sea_orm(primary_key, auto_increment = false)]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Uuid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> user_id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Uuid</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>This uses the very popular <a href="https://crates.io/crates/uuid" target="_blank" rel="noopener noreferrer" class=""><code>uuid</code></a> crate, and SeaORM takes care of converting to/from the PostgreSQL type.</p>
<p>Creating a new record is very easy:</p>
<div class="language-rust codeBlockContainer_HeaP theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_M4gx"><pre tabindex="0" class="prism-code language-rust codeBlock_NXtJ thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_QAHD"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> new_token </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">admin_user</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">ActiveModel</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Set</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">Uuid</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">new_v4</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    user_id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Set</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">user_id</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// ...</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">..</span><span class="token class-name">Default</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">default</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">new_user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">insert</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">conn</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token keyword" style="color:#00009f">await</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>Now how to do this with TSIDs? The <code>tsid</code> create contains a <code>create_tsid</code> function, which returns a <code>TSID</code> struct. We can turn that into a <code>u64</code>, too:</p>
<div class="language-rust codeBlockContainer_HeaP theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_M4gx"><pre tabindex="0" class="prism-code language-rust codeBlock_NXtJ thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_QAHD"><div class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Set</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">create_tsid</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">number</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// ...</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>We also need a way to convert back from <code>u64</code> to the <code>TSID</code> struct. It's all a bit awkward, and the typing is weird: what's a <code>u64</code>? It could be any number, how do we guarantee it's a TSID?</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="building-my-own-adapter">Building my own adapter<a href="https://docs.palform.app/blog/2024/09/04/tsids#building-my-own-adapter" class="hash-link" aria-label="Direct link to Building my own adapter" title="Direct link to Building my own adapter" translate="no">​</a></h2>
<p>It felt like an upward battle at this point, and I kept thinking how much easier it would be to just settle with the beautifully supported UUIDs. But this was getting interesting now, and so I decided to spend nearly an entire week designing a custom adapter. I had a plan.</p>
<p>I wanted my IDs to be <em>type-safe</em>. That is, each table in my database should somehow have its own type of ID, and Rust should complain violently if, for example, I try to use a User ID in a place where a Question ID is needed.</p>
<p>First, I'd need a struct that I can base everything off. This would still involve the <code>tsid</code> crate, just with a lot of wrapping code. Here's how I started:</p>
<div class="language-rust codeBlockContainer_HeaP theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_M4gx"><pre tabindex="0" class="prism-code language-rust codeBlock_NXtJ thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_QAHD"><div class="token-line" style="color:#393A34"><span class="token attribute attr-name" style="color:#00a4db">#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token type-definition class-name">PalformDatabaseID</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">pub</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">crate</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">tsid</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token constant" style="color:#36acaa">TSID</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>Next came the typing. Stripe, famous for its much-loved developer API, does something similar by <a href="https://dev.to/stripe/designing-apis-for-humans-object-ids-3o5a" target="_blank" rel="noopener noreferrer" class="">prefixing IDs</a> with a short code that identifies the resource. For example, customer IDs are prefixed with <code>cus_</code>. Not only does it avoid confusion in code, it's also super readable, as you can tell what an ID is referring to without any additional information.</p>
<p>Inspired by this very satisfying system, I wanted to create something similar.</p>
<p>I created a trait:</p>
<div class="language-rust codeBlockContainer_HeaP theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_M4gx"><pre tabindex="0" class="prism-code language-rust codeBlock_NXtJ thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_QAHD"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">trait</span><span class="token plain"> </span><span class="token type-definition class-name">PalformIDResource</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Eq</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token class-name">PartialEq</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token class-name">Clone</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token class-name">Copy</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token class-name">Hash</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token class-name">Send</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">prefix</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">Option</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">String</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>The prefix is an <code>Option</code> to support certain edge cases where I need to be able to refer to <em>any</em> type of ID in a single field (e.g. audit logs). Where the prefix is unknown, I use <code>None</code>.</p>
<p>Next, I simply created a type implementing this trait for each of my tables:</p>
<div class="language-rust codeBlockContainer_HeaP theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_M4gx"><pre tabindex="0" class="prism-code language-rust codeBlock_NXtJ thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_QAHD"><div class="token-line" style="color:#393A34"><span class="token attribute attr-name" style="color:#00a4db">#[derive(Eq, PartialEq, Clone, Copy, Debug, Hash)]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token type-definition class-name">IDOrganisation</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">impl</span><span class="token plain"> </span><span class="token class-name">PalformIDResource</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> </span><span class="token class-name">IDOrganisation</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">fn</span><span class="token plain"> </span><span class="token function-definition function" style="color:#d73a49">prefix</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">-&gt;</span><span class="token plain"> </span><span class="token class-name">Option</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">String</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token class-name">Some</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"org"</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">to_owned</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>With some macros added in for better readability, you can see <a href="https://github.com/palform/palform/blob/main/packages/tsid/src/resources.rs" target="_blank" rel="noopener noreferrer" class="">all the resource declarations on GitHub</a> (give me a star while you're there <!-- -->❤️<!-- -->).</p>
<p>Then, I modified the <code>PalformDatabaseID</code> struct to include the prefix.</p>
<div class="language-rust codeBlockContainer_HeaP theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_M4gx"><pre tabindex="0" class="prism-code language-rust codeBlock_NXtJ thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_QAHD"><div class="token-line" style="color:#393A34"><span class="token attribute attr-name" style="color:#00a4db">#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token type-definition class-name">PalformDatabaseID</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Resource</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">PalformIDResource</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">pub</span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">crate</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">TSID</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    resource</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">PhantomData</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">Resource</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>Then came the laborious part: adding all the integrations needed for this to work with Serde, SeaORM, Rocket, the OpenAPI generator, etc. You can see <a href="https://github.com/palform/palform/tree/main/packages/tsid/src" target="_blank" rel="noopener noreferrer" class="">everything on GitHub</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="rewriting-the-entities">Rewriting the entities<a href="https://docs.palform.app/blog/2024/09/04/tsids#rewriting-the-entities" class="hash-link" aria-label="Direct link to Rewriting the entities" title="Direct link to Rewriting the entities" translate="no">​</a></h2>
<p>Now, I could modify the SeaORM entities to use my shiny adapter.</p>
<div class="language-rust codeBlockContainer_HeaP theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_M4gx"><pre tabindex="0" class="prism-code language-rust codeBlock_NXtJ thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_QAHD"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">struct</span><span class="token plain"> </span><span class="token type-definition class-name">Model</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token attribute attr-name" style="color:#00a4db">#[sea_orm(primary_key, auto_increment = false)]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">pub</span><span class="token plain"> id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">PalformDatabaseID</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">IDAuthToken</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>A <code>PalformDatabaseID&lt;IDAuthToken&gt;</code> is completely distinct from a <code>PalformDatabaseID&lt;IDOrganisation&gt;</code>, for example. Rust will fully block the compilation if it's somehow mismatched, which is exactly what I wanted.</p>
<p>Generating them is super easy:</p>
<div class="language-rust codeBlockContainer_HeaP theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_M4gx"><pre tabindex="0" class="prism-code language-rust codeBlock_NXtJ thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_QAHD"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> new_form </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token namespace" style="opacity:0.7">form</span><span class="token namespace punctuation" style="opacity:0.7;color:#393A34">::</span><span class="token class-name">ActiveModel</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    id</span><span class="token punctuation" style="color:#393A34">:</span><span class="token plain"> </span><span class="token class-name">Set</span><span class="token punctuation" style="color:#393A34">(</span><span class="token class-name">PalformDatabaseID</span><span class="token punctuation" style="color:#393A34">::</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token class-name">IDForm</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">::</span><span class="token function" style="color:#d73a49">random</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// ...</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<p>In the database, it's still just stored as a type-independent <code>u64</code>. But whenever it's handed to the application, it has to choose a typed prefix, which is also conveyed in the serialised form (e.g. <code>org_0GYDWW6VM4C0E</code>). When being deserialised, the prefix is checked to ensure it matches the requested type; if it's wrong (or there is no prefix), a scary error is returned.</p>
<p>This actually helped catch some errors! In several places, I was using the UUID of the wrong resource without noticing; everything was just <code>Uuid</code> before, and I had to rely on variable names to keep track of what was what.</p>
<p>For future development, it will also inevitably reduce bugs and small but high-consequence typos. It will likely even improve the security posture of Palform, which is absolutely essential with such a security-focussed application. Developers are only humans and even the most careful ones will make mistakes; this change, however, will stop the mistakes with big scary red error messages before they can cause any damage.</p>
<p>It's also simply more Rust-like, which I'm sure will make the Rust people very happy.</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="sharing-the-code">Sharing the code<a href="https://docs.palform.app/blog/2024/09/04/tsids#sharing-the-code" class="hash-link" aria-label="Direct link to Sharing the code" title="Direct link to Sharing the code" translate="no">​</a></h2>
<p>Palform is <a href="https://github.com/palform/palform/" target="_blank" rel="noopener noreferrer" class="">open source in its entirety</a>, currently under the AGPL license. The ID management is under the <code>packages/tsid</code> directory, but I might release it as a more liberally licensed separate module in the near future, so that everyone building web apps in Rust can benefit from these performance, security, and stability improvements.</p>
<p>In the meantime, if you're ever in need of a form builder that actually cares about encryption, privacy, scalability, and other ethical principles, give <a href="https://palform.app/" target="_blank" rel="noopener noreferrer" class="">Palform</a> a try (it's free with unlimited responses).</p>
<blockquote>
<p>Thanks for reading! This article was written by <a href="https://www.linkedin.com/in/palkerecs" target="_blank" rel="noopener noreferrer" class="">Pal Kerecsenyi</a>, the founder of Palform. Last updated 04/09/2024.</p>
</blockquote>
<blockquote>
<p>If you have any questions or found a mistake, please email me at <a href="mailto:pal@palform.app" target="_blank" rel="noopener noreferrer" class="">pal@palform.app</a>.</p>
</blockquote>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The 7 best form builders in 2024]]></title>
            <link>https://docs.palform.app/blog/2024/09/03/form-builders-2024</link>
            <guid>https://docs.palform.app/blog/2024/09/03/form-builders-2024</guid>
            <pubDate>Tue, 03 Sep 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[It's a hotly contested topic, and everyone has their own personal opinions! In the end, it boils down to what your use case is, who's filling out the forms, and how many responses you're expecting. Different form builders serve vastly different niches, and it's important to understand the differences.]]></description>
            <content:encoded><![CDATA[<p>It's a hotly contested topic, and everyone has their own personal opinions! In the end, it boils down to what your use case is, who's filling out the forms, and how many responses you're expecting. Different form builders serve vastly different niches, and it's important to understand the differences.</p>
<p>We'll keep it nice and brief: having researched dozens of competing services in this <em>very</em> crowded market, I've selected the best options. Most other comparison sites agree on most of these services.</p>
<div class="theme-admonition theme-admonition-info admonition__oF4 alert alert--info"><div class="admonitionHeading_xfBx"><span class="admonitionIcon_MkaD"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_FPB_"><p>This content is written for <strong>Palform</strong>, one of the mentioned form builders. We'll try to keep the article neutral, but keep in mind we might be biased!</p><p>We've researched the content on September 2nd, so it may have become inaccurate since then.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="palform"><a href="https://palform.app/" target="_blank" rel="noopener noreferrer" class="">Palform</a><a href="https://docs.palform.app/blog/2024/09/03/form-builders-2024#palform" class="hash-link" aria-label="Direct link to palform" title="Direct link to palform" translate="no">​</a></h2>
<p>A strong new player in the field, Palform places a special focus on privacy and security. It uses sophisticated <strong>end-to-end encryption</strong> technology, while also having the full range of features and simplicity you'd expect of any other form builder. It's also fully open source!</p>
<p>However, due to it's young status and thorough encryption, the range of 3rd-party integrations is limited, with email/webhook being the only currently available options.</p>
<p>More features <a class="" href="https://docs.palform.app/roadmap">are being developed</a> constantly.</p>
<p><img decoding="async" loading="lazy" alt="Palform landing page" src="https://docs.palform.app/assets/images/palform-889ed083cecbc8cab91e428417678d7b.png" width="1189" height="743" class="img_al4G"></p>
<h3 class="anchor anchorTargetStickyNavbar__jMZ" id="best-for">Best for<a href="https://docs.palform.app/blog/2024/09/03/form-builders-2024#best-for" class="hash-link" aria-label="Direct link to Best for" title="Direct link to Best for" translate="no">​</a></h3>
<ul>
<li class="">Showing your customers they can trust you.<!-- -->
<ul>
<li class="">The higher security guarantees let form-fillers know their data is safe, and places your reputation ahead of your competitors'</li>
</ul>
</li>
<li class="">Handling any kind of sensitive data</li>
<li class="">Users experienced with Google or Microsoft Forms, and wanting an easy-to-use solution with no coding</li>
<li class="">Generating beautiful actionable reports without any stats knowledge</li>
<li class="">Cases where open-source software is a must</li>
<li class="">Saving money</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar__jMZ" id="pricing">Pricing<a href="https://docs.palform.app/blog/2024/09/03/form-builders-2024#pricing" class="hash-link" aria-label="Direct link to Pricing" title="Direct link to Pricing" translate="no">​</a></h3>
<ul>
<li class=""><strong>Unlimited responses</strong> included in the free plan</li>
<li class="">Higher plans up to ~$80/m have more features, e.g. for corporate compliance</li>
<li class="">Discounted pricing offered for students and non-profits</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="typeform"><a href="https://www.typeform.com/" target="_blank" rel="noopener noreferrer" class="">Typeform</a><a href="https://docs.palform.app/blog/2024/09/03/form-builders-2024#typeform" class="hash-link" aria-label="Direct link to typeform" title="Direct link to typeform" translate="no">​</a></h2>
<p>A long-running and controversial option, Typeform popularised the "one question at a time" way of doing forms. It features easy-to-build aesthetic designs and slick animations, as well as powerful data analyses.</p>
<p>However, the animations and layout may be overwhelming and confusing for some users who are not super comfortable with technology.</p>
<p><img decoding="async" loading="lazy" alt="Typeform landing page" src="https://docs.palform.app/assets/images/typeform-8b94fe7b7bddce94bde4ac4f0d4e7227.png" width="1592" height="760" class="img_al4G"></p>
<h3 class="anchor anchorTargetStickyNavbar__jMZ" id="best-for-1">Best for<a href="https://docs.palform.app/blog/2024/09/03/form-builders-2024#best-for-1" class="hash-link" aria-label="Direct link to Best for" title="Direct link to Best for" translate="no">​</a></h3>
<ul>
<li class="">Forms that are more about the "experience" and where one-at-a-time questions make sense</li>
<li class="">Very small expected response counts</li>
<li class="">Environments where budget doesn't matter</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar__jMZ" id="pricing-1">Pricing<a href="https://docs.palform.app/blog/2024/09/03/form-builders-2024#pricing-1" class="hash-link" aria-label="Direct link to Pricing" title="Direct link to Pricing" translate="no">​</a></h3>
<p>Notoriously, the pricing is amongst the highest out of all form builders, with the free plan <strong>only offering 10 responses/month</strong>.</p>
<p>Even the Basic plan, for <strong>21EUR/mo</strong> only includes <strong>100 response/month</strong>.</p>
<p>Plans go up to 75EUR/mo for 10,000 responses and more advanced features.</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="jotform"><a href="https://www.jotform.com/" target="_blank" rel="noopener noreferrer" class="">Jotform</a><a href="https://docs.palform.app/blog/2024/09/03/form-builders-2024#jotform" class="hash-link" aria-label="Direct link to jotform" title="Direct link to jotform" translate="no">​</a></h2>
<p>A versatile, tried-and-test form builder, Jotform is capable of building forms in loads of different designs and layouts. The application is also very feature-rich, with extras such as PDF forms and built-in templates. E-signatures are also supported, with highly-rated 24/7 customer support.</p>
<p><img decoding="async" loading="lazy" alt="Jotform landing page" src="https://docs.palform.app/assets/images/jotform-4d789205cdb968445ac7341ba9fec72b.png" width="1404" height="762" class="img_al4G"></p>
<p>It even supports encrypted forms, although in a much more lightweight and barebones way than the integrated experience offered by <a href="https://palform.app/" target="_blank" rel="noopener noreferrer" class="">Palform</a>.</p>
<h3 class="anchor anchorTargetStickyNavbar__jMZ" id="best-for-2">Best for<a href="https://docs.palform.app/blog/2024/09/03/form-builders-2024#best-for-2" class="hash-link" aria-label="Direct link to Best for" title="Direct link to Best for" translate="no">​</a></h3>
<ul>
<li class="">Large enterprises needing compliance with strict standards such as HIPAA</li>
<li class="">Users who are happy to plan to meet the complex pricing requirements</li>
<li class="">Users wanting to save some time with pre-built templates</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar__jMZ" id="pricing-2">Pricing<a href="https://docs.palform.app/blog/2024/09/03/form-builders-2024#pricing-2" class="hash-link" aria-label="Direct link to Pricing" title="Direct link to Pricing" translate="no">​</a></h3>
<p>The free plan includes <strong>100 submissions/month</strong>, 10x more than Typeform. However, to continue beyond that, you need to pay <strong>at least $34/mo</strong> for the next plan.</p>
<p>Many, <em>many</em> different values are limited by the plan specifications, including:</p>
<ul>
<li class="">Form submissions</li>
<li class="">Form <em>views</em></li>
<li class="">Users</li>
<li class="">Storage space</li>
<li class=""><em>Stored</em> submissions at a given time</li>
<li class="">Fields per form</li>
<li class="">E-signatures</li>
</ul>
<p>If you need more of just one of these limits, you'll need to upgrade your plan, meaning it can get surprisingly expensive quite quickly.</p>
<p>However, it's definitely much better value-for-money than Typeform.</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="youform"><a href="https://youform.com/" target="_blank" rel="noopener noreferrer" class="">Youform</a><a href="https://docs.palform.app/blog/2024/09/03/form-builders-2024#youform" class="hash-link" aria-label="Direct link to youform" title="Direct link to youform" translate="no">​</a></h2>
<p>A relatively new product, Youform has the same focus on simplicity as Palform, except targetting the Typeform one-question-at-a-time model.</p>
<p>It has a commendably ethical pricing model that makes planning your costs much simpler.</p>
<p>The design is very clean, and absolutely anyone can use it without experience.</p>
<p>Having tested it for a few days, the interface is genuinely very smooth and user friendly. The user reviews are right to sound so excited! Unlike most form builders though, the admin panel doesn't work on mobile. Checking your responses on the go is quite difficult sadly.</p>
<p>It lacks the ultra-high security and privacy guarantees of <a href="https://palform.app/" target="_blank" rel="noopener noreferrer" class="">Palform</a>.</p>
<p><img decoding="async" loading="lazy" alt="Youform landing page" src="https://docs.palform.app/assets/images/youform-2f106018fbd8e2908f31af823169badb.png" width="1246" height="902" class="img_al4G"></p>
<h3 class="anchor anchorTargetStickyNavbar__jMZ" id="best-for-3">Best for<a href="https://docs.palform.app/blog/2024/09/03/form-builders-2024#best-for-3" class="hash-link" aria-label="Direct link to Best for" title="Direct link to Best for" translate="no">​</a></h3>
<ul>
<li class="">People looking for a close Typeform alternative for a fraction of the price</li>
<li class="">Simple use cases without high security guarantees<!-- -->
<ul>
<li class="">Data is hosted in the USA, so it might not be suitably GDPR compliant. But that's not legal advice!</li>
</ul>
</li>
<li class="">Saving money</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar__jMZ" id="pricing-3">Pricing<a href="https://docs.palform.app/blog/2024/09/03/form-builders-2024#pricing-3" class="hash-link" aria-label="Direct link to Pricing" title="Direct link to Pricing" translate="no">​</a></h3>
<p>Unlimited responses and most features for <strong>free</strong>, then $29/mo for further features.</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="google-forms"><a href="https://www.google.com/forms/about/" target="_blank" rel="noopener noreferrer" class="">Google Forms</a><a href="https://docs.palform.app/blog/2024/09/03/form-builders-2024#google-forms" class="hash-link" aria-label="Direct link to google-forms" title="Direct link to google-forms" translate="no">​</a></h2>
<p>Ahhhh a good old classic. Google Forms continues to be the backbone of low-stakes data collection around the world.</p>
<p>The interface is really simple, and hasn't changed much over the years. As Google does not directly make any income from Google Forms, it's likely the development of new features isn't a huge priority. Customer support is also very limited or in most cases completely impossible.</p>
<p>Of course, as with all Google products, there are <a class="" href="https://docs.palform.app/blog/2024/08/27/secure-your-forms">serious data protection concerns</a>. Your data might be stored in the US, making it essentially unusable for any commercial data handling in the EU unless you fulfill an extremely complicated and technical legal framework.</p>
<p>Generally, Google Forms don't really look professional anymore. If a business is seriously using them, it just screams "low effort". Fortunately, there's many alternatives that are just as easy to use but produce a far prettier result.</p>
<p><img decoding="async" loading="lazy" alt="Google Forms info page" src="https://docs.palform.app/assets/images/googleforms-ceaa6fe0833864e059283f15e5b9f6c3.png" width="1902" height="728" class="img_al4G"></p>
<p>The question types are also somewhat limited, and the boolean branching rules are very primitive.</p>
<p>Okay. Sorry. That's enough roasting Google Forms. I'm sorry if you're a passionate fan. We can continue in peace now.</p>
<h3 class="anchor anchorTargetStickyNavbar__jMZ" id="best-for-4">Best for<a href="https://docs.palform.app/blog/2024/09/03/form-builders-2024#best-for-4" class="hash-link" aria-label="Direct link to Best for" title="Direct link to Best for" translate="no">​</a></h3>
<ul>
<li class="">Very <em>very</em> simple use cases between family and friends, or for small informal events.</li>
<li class="">Cases where brand identity doesn't matter at all</li>
<li class="">Cases where no personal data is being collected</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar__jMZ" id="pricing-4">Pricing<a href="https://docs.palform.app/blog/2024/09/03/form-builders-2024#pricing-4" class="hash-link" aria-label="Direct link to Pricing" title="Direct link to Pricing" translate="no">​</a></h3>
<p>The consumer version is <strong>free</strong>! With no meaningful limits beyond the Google Drive file upload limit.</p>
<p><a href="https://workspace.google.com/pricing.html" target="_blank" rel="noopener noreferrer" class="">Google Workspace</a> (a paid service) includes a very slightly more advanced version, where you can set <a href="https://support.google.com/a/answer/14310028?hl=en" target="_blank" rel="noopener noreferrer" class="">data sovereignty constraints</a> so that you can legally handle the personal data of EU citizens.</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="fillout"><a href="https://www.fillout.com/" target="_blank" rel="noopener noreferrer" class="">Fillout</a><a href="https://docs.palform.app/blog/2024/09/03/form-builders-2024#fillout" class="hash-link" aria-label="Direct link to fillout" title="Direct link to fillout" translate="no">​</a></h2>
<p>Another tool similar to Jotform, Fillout creates pretty, mobile-friendly forms of any shape and size. Unlike most competitors, it also supports real-time collaboration, making it particularly suitable for teams working together on authoring forms.</p>
<p>It also comes with advanced tangential features, such as event scheduling and payment, built right in.</p>
<p><img decoding="async" loading="lazy" alt="Fillout forms landing page" src="https://docs.palform.app/assets/images/fillout-ff89c346f03ff3110ea8e0de32b7f8f6.png" width="1332" height="725" class="img_al4G"></p>
<h3 class="anchor anchorTargetStickyNavbar__jMZ" id="best-for-5">Best for<a href="https://docs.palform.app/blog/2024/09/03/form-builders-2024#best-for-5" class="hash-link" aria-label="Direct link to Best for" title="Direct link to Best for" translate="no">​</a></h3>
<ul>
<li class="">Real-time collaboration</li>
<li class="">Versatile designs within one app<!-- -->
<ul>
<li class="">Instead of a Typeform-style app and Google-style app separately, Fillout can do both</li>
</ul>
</li>
<li class="">Building more complex automated pipelines involving your forms using integrations</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar__jMZ" id="pricing-5">Pricing<a href="https://docs.palform.app/blog/2024/09/03/form-builders-2024#pricing-5" class="hash-link" aria-label="Direct link to Pricing" title="Direct link to Pricing" translate="no">​</a></h3>
<ul>
<li class="">Generous free plan with most features included, and <strong>up to 1000 responses/month</strong></li>
<li class="">Plans with increasing response limits and more features</li>
<li class="">For <strong>$75/month</strong> you get <em>unlimited</em> responses</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="microsoft-forms"><a href="https://www.microsoft.com/en-gb/microsoft-365/online-surveys-polls-quizzes" target="_blank" rel="noopener noreferrer" class="">Microsoft Forms</a><a href="https://docs.palform.app/blog/2024/09/03/form-builders-2024#microsoft-forms" class="hash-link" aria-label="Direct link to microsoft-forms" title="Direct link to microsoft-forms" translate="no">​</a></h2>
<p>Another classic, Microsoft's flagship data collection service actually keeps surprising. Unlike Google, new features are constantly added to this, such as the new AI-generated question suggestions.</p>
<p>The design can feel clunky occasionally (that's a personal opinion) and the loading times are often slow (both on the editing and filling side), especially if signing in with a Microsoft account is required.</p>
<p>Despite that, it's fairly easy to make good-looking forms, and it even features decently rich branching rules and question types. Still, lots of obvious genuinely useful types, such as address auto-complete inputs, are missing. But it's great to see that a product that has mostly non-paying users is still developed so actively!</p>
<p>And again, similarly to Google, Microsoft is an enormous ad-tech corporation. They haven't always been reliable with handling personal data, and employers using certain Office 365 plans get wide-ranging <a href="https://www.computerweekly.com/news/252521757/Microsoft-Office-365-has-ability-to-spy-on-workers" target="_blank" rel="noopener noreferrer" class="">worker surveillance powers</a>.</p>
<p><img decoding="async" loading="lazy" alt="Microsoft Forms landing page" src="https://docs.palform.app/assets/images/microsoftforms-30c7eaa4d4251fb1c184b1120483d32e.png" width="1665" height="663" class="img_al4G"></p>
<p>Similarly to Google Forms, the data location is a bit of a pain point which makes targetting EU customers very tricky. Unless you're an EU-based Microsoft 365 customer, your Forms data <a href="https://learn.microsoft.com/en-us/microsoft-365/enterprise/m365-dr-workload-other?view=o365-worldwide#forms" target="_blank" rel="noopener noreferrer" class="">will be stored in the US</a> (or Australia if you're based there). That might mean any EU user who fills in your form will have their data transferred to the US without their explicit knowledge or consent, which could be a GDPR violation.</p>
<h3 class="anchor anchorTargetStickyNavbar__jMZ" id="best-for-6">Best for<a href="https://docs.palform.app/blog/2024/09/03/form-builders-2024#best-for-6" class="hash-link" aria-label="Direct link to Best for" title="Direct link to Best for" translate="no">​</a></h3>
<ul>
<li class="">Large corporations wanting to keep all their data within Microsoft 365</li>
<li class="">Similar simple use cases as Google Forms</li>
<li class="">Speedy form writing with AI-generated questions</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar__jMZ" id="pricing-6">Pricing<a href="https://docs.palform.app/blog/2024/09/03/form-builders-2024#pricing-6" class="hash-link" aria-label="Direct link to Pricing" title="Direct link to Pricing" translate="no">​</a></h3>
<ul>
<li class="">Responses always <strong>essentially unlimited</strong>
<ul>
<li class="">The limit is defined by the amount of cloud storage space your account has</li>
</ul>
</li>
<li class="">Free for personal use</li>
<li class="">Available on all paid Microsoft 365 plans, starting at <strong>$6/user/month</strong>
<ul>
<li class="">Most other form builders don't use a per-user pricing model; Microsoft does, as it's part of a wider office suite package. It's not currently possible to purchase a Forms subscription separately.</li>
</ul>
</li>
</ul>
<hr>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="pricing-overview">Pricing overview<a href="https://docs.palform.app/blog/2024/09/03/form-builders-2024#pricing-overview" class="hash-link" aria-label="Direct link to Pricing overview" title="Direct link to Pricing overview" translate="no">​</a></h2>
<p>Response limits are the most common billing model for commercial form builders. In this table, we compare the reviewed form builders and their limit vs price value.</p>
<p>The values in this table are based on annual plans in USD.</p>
<table><thead><tr><th><strong>Form builder</strong></th><th><strong>Responses for free</strong></th><th><strong>Cheapest paid plan; included responses</strong></th><th><strong>Most expensive plan; included responses</strong></th></tr></thead><tbody><tr><td><strong>Palform</strong></td><td>Unlimited</td><td>$5/month; unlimited</td><td>$83/month; unlimited</td></tr><tr><td><strong>Typeform</strong></td><td>10/month</td><td>$23/month; 100/month</td><td>$83/month; 10,000/month</td></tr><tr><td><strong>Jotform</strong></td><td>100/month</td><td>$34/month; 1,000/month</td><td>$49/month; 5,000/month</td></tr><tr><td><strong>Youform</strong></td><td>Unlimited</td><td>$29/month; unlimited</td><td>$29/month; unlimited</td></tr><tr><td><strong>Google Forms</strong></td><td>Unlimited</td><td>$6/user/month; unlimited</td><td>$18/user/month; unlimited</td></tr><tr><td><strong>Fillout</strong></td><td>1,000/month</td><td>$15/month; 2,000/month</td><td>$75/month; unlimited</td></tr><tr><td><strong>Microsoft Forms</strong></td><td>Unlimited</td><td>$6/user/month; unlimited</td><td>$24/user/month; unlimited</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="so-which-one-should-i-go-with">So which one should I go with???<a href="https://docs.palform.app/blog/2024/09/03/form-builders-2024#so-which-one-should-i-go-with" class="hash-link" aria-label="Direct link to So which one should I go with???" title="Direct link to So which one should I go with???" translate="no">​</a></h2>
<p>It depends. Sorry. There is no straightforward answer.</p>
<p>We can roughly categorise these 7 tools by use case:</p>
<ul>
<li class=""><strong>General purpose</strong>: use these for any non-trivial data collection, big or small<!-- -->
<ul>
<li class="">Palform, Youform, Fillout</li>
<li class="">These all have unlimited plans, making it easy to scale without having to worry about surprise charges</li>
</ul>
</li>
<li class=""><strong>High security/privacy</strong>: use these when you're collecting sensitive data, such as medical or financial information<!-- -->
<ul>
<li class="">Palform</li>
</ul>
</li>
<li class=""><strong>Low-stakes informal surveys</strong>
<ul>
<li class="">Microsoft Forms and Google Forms</li>
</ul>
</li>
<li class=""><strong>Advanced automation</strong>
<ul>
<li class="">Jotform, Fillout</li>
</ul>
</li>
<li class=""><strong>Beautiful, flashy, animated design</strong>
<ul>
<li class="">Typeform</li>
</ul>
</li>
</ul>
<p>This is not exhaustive, and a lot of these form builders are versatile enough to be used for different use cases! I hope this guide gave you a decent insight into the world of form builders, and what to look for when choosing one.</p>
<p>My best advice is this: go out and try them! All of these services have free trials: make a MVP form that replicates whatever form you're actually intending to build, and see how easy the process is.</p>
<hr>
<blockquote>
<p>Thanks for reading! If you have any questions about data collection or forms, feel free to send me an email! I'm happy to discuss and advise your problem, even if you're using other form builders.</p>
</blockquote>
<blockquote>
<p>Email: <a href="mailto:pal@palform.app" target="_blank" rel="noopener noreferrer" class="">pal@palform.app</a></p>
</blockquote>
<blockquote>
<p>Follow <a href="https://www.linkedin.com/company/palform/" target="_blank" rel="noopener noreferrer" class="">Palform on Linkedin</a> to keep up to date with our helpful articles and resources!</p>
</blockquote>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Palform is now open source!]]></title>
            <link>https://docs.palform.app/blog/2024/09/02/open-source</link>
            <guid>https://docs.palform.app/blog/2024/09/02/open-source</guid>
            <pubDate>Mon, 02 Sep 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Go check it out on GitHub! And maybe give me a if you feel like it]]></description>
            <content:encoded><![CDATA[<blockquote>
<p>Go <a href="https://github.com/palform/palform/" target="_blank" rel="noopener noreferrer" class="">check it out on GitHub</a>! And maybe give me a <!-- -->⭐<!-- --> if you feel like it</p>
</blockquote>
<p>I strongly believe all software with even the slightest security requirement should be open source. Instead of <a href="https://en.wikipedia.org/wiki/Security_through_obscurity" target="_blank" rel="noopener noreferrer" class="">security through obscurity</a>, keeping the code open will help <em>reduce</em> vulnerabilities. The entire community will be easily able to find mistakes and bugs and get them fixed way faster.</p>
<p>When I started working on Palform, it was a fun side project to improve the way I collected data. Mostly just to fix my personal problems with all the other form builders out there. Deep down, I always intended for it to be open source. Especially since the client-side performs a lot of crucial encryption work, it's essential to be able to see exactly what's going on.</p>
<p>I lovingly use many other open source SaaS tools such as the <a href="https://proton.me/" target="_blank" rel="noopener noreferrer" class="">Proton</a> suite, <a href="https://plausible.io/" target="_blank" rel="noopener noreferrer" class="">Plausible Analytics</a>, <a href="https://www.keycloak.org/" target="_blank" rel="noopener noreferrer" class="">Keycloak</a>, etc. I think the "open source but supported by an <em>official</em> paid SaaS offering" is one of the most sustainable way to do open source projects (besides very large ones such as Linux, which already have a huge amount of volunteers). Otherwise, burnout sets in eventually, because developer time is never truly <em>free</em>. Of course, there are exceptions to this, but in general I feel this is a more stable model, despite the possible conflicts of interest that occasionally arise.</p>
<p>My aim with Palform is to ensure everyone can comfortably trust it with very sensitive categories of personal data, the kind you just wouldn't submit in a regular Google Form. This will hopefully move the project closer to building that trust.</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="licensing">Licensing<a href="https://docs.palform.app/blog/2024/09/02/open-source#licensing" class="hash-link" aria-label="Direct link to Licensing" title="Direct link to Licensing" translate="no">​</a></h2>
<p>It's always a big question.</p>
<p>For now, I've opted for the <a href="https://www.gnu.org/licenses/agpl-3.0.en.html" target="_blank" rel="noopener noreferrer" class="">GNU AGPL</a>. Perhaps my inner fears of some evil megacorporation taking my code to build a data-stealing version of Palform are what kept me from going for something simpler like the MIT license. Realistically, that's unlikely to happen, but you never know...</p>
<p>In any case, I don't think there <em>should</em> be a situation where a modification to my source code on a cloud-hosted service shouldn't be made public. That would just inherently be dodgy.</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="contributions">Contributions<a href="https://docs.palform.app/blog/2024/09/02/open-source#contributions" class="hash-link" aria-label="Direct link to Contributions" title="Direct link to Contributions" translate="no">​</a></h2>
<p>...are welcome! Of course, it'll take some time until I can document everything about the codebase to a point where it's easy and accessible to contributors. But if you feel like browsing through some Rust code to fix any bugs, I would love that too!</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[You should stop using Google Forms]]></title>
            <link>https://docs.palform.app/blog/2024/08/27/secure-your-forms</link>
            <guid>https://docs.palform.app/blog/2024/08/27/secure-your-forms</guid>
            <pubDate>Tue, 27 Aug 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[I'm Pal, the founder and developer behind Palform, a more secure and full-featured alternative to Google and Microsoft Forms. The idea started when, earlier this year, I noticed a problem with how I collect data when working on projects.]]></description>
            <content:encoded><![CDATA[<p>I'm Pal, the founder and developer behind <a href="https://palform.app/" target="_blank" rel="noopener noreferrer" class="">Palform</a>, a more secure and full-featured alternative to Google and Microsoft Forms. The idea started when, earlier this year, I noticed a problem with how I collect data when working on projects.</p>
<p>More often than not, I often found myself in need of a way to collect data from large groups of people related to my work. I needed to create survey-style questionairres, quickly and without too much hassle. Almost every single time, I defaulted to Microsoft or Google forms, like it was muscle memory. These tools were simply <em>good enough</em>.</p>
<p>They were both</p>
<ul>
<li class="">easy</li>
<li class="">extremely popular</li>
<li class="">always free</li>
<li class="">just <em>there</em>, requiring zero added research into other products</li>
<li class="">integrated into whatever ecosystem I was using</li>
</ul>
<p>In this article, I'll explain why these tools were actually quite problematic, and what I created to try and solve these problems.</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="so-whats-the-problem">So what's the problem?<a href="https://docs.palform.app/blog/2024/08/27/secure-your-forms#so-whats-the-problem" class="hash-link" aria-label="Direct link to So what's the problem?" title="Direct link to So what's the problem?" translate="no">​</a></h2>
<p>Both these tools felt like I was missing something. Many of my end-users made frequent complaints about the privacy records of these companies, and said they felt uncomfortable providing their data through them.</p>
<p>The truth is, Google could see all of your form responses if it wanted to. As a policy, <a href="https://support.google.com/googlecloud/answer/6056650?sjid=13208649007061461515-EU" target="_blank" rel="noopener noreferrer" class="">they don't</a>. But still, I felt weird trusting the world's largest ad-tech corporation with so much data; it's not exactly rare for mega-companies to violate their own terms.</p>
<p>Then there was the question of sovereignty. Google Forms is hosted in the US, EU, and various other places around the world. In the vast majority of non-enterprise use cases (e.g. if you're not <a href="https://support.google.com/a/answer/14310028?hl=en" target="_blank" rel="noopener noreferrer" class="">using Google Workspace</a> or <a href="https://workspace.google.com/pricing" target="_blank" rel="noopener noreferrer" class="">your plan isn't good enough</a>), you don't even get a say in <em>where</em> the data is stored. Data transfers between the EU and US (based on the <a href="https://commission.europa.eu/law/law-topic/data-protection/international-dimension-data-protection/eu-us-data-transfers_en" target="_blank" rel="noopener noreferrer" class="">EU adequacy decision</a>) require complying with a <a href="https://www.dataprivacyframework.gov/key-requirements" target="_blank" rel="noopener noreferrer" class="">complex legal framework</a>. Since you could be transferring EU user data to the US (or maybe not, you just don't know!), <strong>you have to comply with this framework</strong> if you use Google Forms outside of a Workspace plan that supports limiting your data to a specific region. To me, this was evidently <em>extremely overkill</em> for almost all use-cases.</p>
<p>Of course, there are several excellent <a href="https://www.typeform.com/" target="_blank" rel="noopener noreferrer" class="">European</a> <a href="https://www.limesurvey.org/" target="_blank" rel="noopener noreferrer" class="">companies</a> providing form builders. But none of them properly address the growing problem of security. In a data breach, it would still be easily possible for hundreds of thousands of sensitive responses to be leaked. It's a <a href="https://www.idtheftcenter.org/post/itrc-sees-third-most-data-breach-victims-in-quarter/" target="_blank" rel="noopener noreferrer" class="">growing problem in 2024</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="my-solution">My solution<a href="https://docs.palform.app/blog/2024/08/27/secure-your-forms#my-solution" class="hash-link" aria-label="Direct link to My solution" title="Direct link to My solution" translate="no">​</a></h2>
<p>I wanted to solve this problem, and create a form builder I actually enjoyed using. One that didn't make me and my end-users stress about a random third-party having access to extremely sensitive personal information.</p>
<p>Naturally, I turned to <a href="https://en.wikipedia.org/wiki/Encryption" target="_blank" rel="noopener noreferrer" class="">encryption</a>. What if there was a way to <em>mathematically</em> guarantee the security and privacy of my users?</p>
<p>The design is simple:</p>
<ul>
<li class="">Everyone in your team has a public/private key pair</li>
<li class="">When a form is submitted, it's encrypted with the public keys</li>
<li class="">Palform stores the encrypted response. I can't see its contents. Nobody can. Not even government authorities.</li>
<li class="">Your browser downloads the response, and decrypts it using your private key. You get nice pretty graphs, and full peace of mind!</li>
</ul>
<p>It's backed by a tried and tested algorithm suite known as <a href="https://www.openpgp.org/" target="_blank" rel="noopener noreferrer" class="">OpenPGP</a>. Millions of emails are regularly sent this way, e.g. using <a href="https://proton.me/mail" target="_blank" rel="noopener noreferrer" class="">Proton Mail</a>. Its security has been backed by decades of research, and <a href="https://www.openpgp.org/about/history/" target="_blank" rel="noopener noreferrer" class="">remains unbroken by governments</a> (as far as we know).</p>
<p>You can read about all this in more detail <a class="" href="https://docs.palform.app/keys/technical">in our documentation</a> if you care.</p>
<p>I wanted this to be something everyone could use, so I had to avoid requiring users to understand what all these complex algorithms were. You should be able to go from Google Forms to Palform without even really thinking about it. WhatsApp, Signal, Proton, and many other tools had already mastered the art of providing secure encryption despite many of their users not understanding what <em>encryption</em> means.</p>
<p><strong>Palform handles all the encryption in the background</strong>. You just have to click a <em>Generate Key</em> button once (when you set up your account), and it's stored nice and safely in your browser. An encrypted backup also gets saved to the server, for which you need to save a key password (similar to the backup key in WhatsApp, for example).</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="making-it-full-featured">Making it full-featured<a href="https://docs.palform.app/blog/2024/08/27/secure-your-forms#making-it-full-featured" class="hash-link" aria-label="Direct link to Making it full-featured" title="Direct link to Making it full-featured" translate="no">​</a></h2>
<p>Encryption is cool, but it's not really a selling point unless the form builder itself is just as good as (or preferably better) than competitors. That's why Palform emphasises supporting <strong>loads of question types</strong>.</p>
<p>Some particularly interesting ones are:</p>
<ul>
<li class="">Address auto-complete</li>
<li class="">E-signature (I'm considering working on eIDAS compliance)</li>
<li class="">Encrypted file upload</li>
<li class="">"Hidden" questions that take a value from a URL parameter</li>
</ul>
<p>I want the company to have a focus on privacy above all else, so I've included <strong>compliance-centric features</strong> such as:</p>
<ul>
<li class=""><strong>submission auto-delete</strong> (after a given number of days)</li>
<li class="">OpenID/OAuth so you don't even have to trust me with your credentials</li>
<li class="">team/user permission management</li>
<li class="">Cloudflare-based privacy-friendly captcha</li>
<li class="">and more!</li>
</ul>
<p>And of course there's dozens of features that make it much more full-featured than Google Forms:</p>
<ul>
<li class=""><strong>Very thorough branding customisation</strong> for a better white-label experience</li>
<li class="">Advanced branching rules between question pages</li>
<li class="">More specific customisable validation, depending on the question types</li>
<li class="">Markdown-enabled description fields</li>
<li class="">Automatic correlation analysis between questions in your responses</li>
<li class="">Export responses to multiple formats</li>
<li class=""><a class="" href="https://docs.palform.app/roadmap">and more coming soon</a>!</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="it-wasnt-easy">It wasn't easy<a href="https://docs.palform.app/blog/2024/08/27/secure-your-forms#it-wasnt-easy" class="hash-link" aria-label="Direct link to It wasn't easy" title="Direct link to It wasn't easy" translate="no">​</a></h2>
<p>End-to-end encryption really upsets a lot of the things in forms that everyone (including myself) takes for granted.</p>
<ul>
<li class="">When handling <strong>huge amounts of data</strong>, Google Forms can simply generate a pretty overview chart server-side and avoid downloading dozens of megabytes into your browser. Palform cannot, because our server cannot see your data. Instead, we use caching algorithms to progressively stream just the correct minimal responses. We use WASM-based binaries to speed up the process, and depending on your browser, we even support multi-threading. You'll only have to wait a few minutes to decrypt tens of thousands of responses, and from then on it'll load instantly thanks to the cache.</li>
<li class="">Some form builders support <strong>webhooks</strong>, where response data is sent to an endpoint of your choice immediately upon a form submission. Palform sends the encrypted data instead. Because OpenPGP keys are so open, you can easily use a server-side key to decrypt the data.</li>
<li class=""><strong>Integrations</strong> with third-party apps are basically impossible to offer, unless the app supports decrypting data using a PGP key. I'm trying to solve this by including as many commonly-used 3rd-party features in Palform as possible, but <em>this is still a work-in-progress</em>.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="how-much-should-it-cost">How much should it cost?<a href="https://docs.palform.app/blog/2024/08/27/secure-your-forms#how-much-should-it-cost" class="hash-link" aria-label="Direct link to How much should it cost?" title="Direct link to How much should it cost?" translate="no">​</a></h2>
<p>Firstly, Palform is <em>not</em> open source at the moment. I understand it's especially important for encryption/security-oriented products to be at least source available, but open sourcing an application hard, and involves a lot of <a href="https://www.theregister.com/2011/06/22/open_source_is_hard/" target="_blank" rel="noopener noreferrer" class="">non-trivial decisions</a>. Palform will be open-sourced at some point in the very near future, most likely under AGPL or a similar license. I might introduce a self-hosted version too, but that's too complicated for now.</p>
<p>Obviously, Google Forms is free. So is Microsoft Forms. But they're not truly "free". Their existence is supported by income from vast advertising networks and shady practices. You're indirectly profiting from <em>Google's exploitation</em> by using Forms.</p>
<p>Okay maybe that's me being a little dramatic. You're allowed to use Google Forms if you want, but please make sure you understand the risks, especially if you're storing something sensitive.</p>
<p>Unfortunately, <strong>Palform needs to cost money</strong>. Hosting infrastructure and spending time working on new features is pricey, and I want it to operate without dodgy VC funding (and definitely without being subsidised by an advertising network).</p>
<p>Some of Palform's <a href="https://www.typeform.com/pricing/" target="_blank" rel="noopener noreferrer" class="">competitors</a> have unreasonable, arguably <em>bizarre</em> pricing structures. I'm not the only one who feels that way. There's definitely no way the operating costs are quite that high.</p>
<p>I tried to keep it simple and predictable. So here's how I wanted it to work:</p>
<ul>
<li class=""><strong>All plans get unlimited responses</strong>.<!-- -->
<ul>
<li class="">Responses don't really cost much money to process, since your browser does most of the work.</li>
</ul>
</li>
<li class="">There's a free (forever) plan, also with unlimited responses, but with a limited number of forms/questions, and fewer features.</li>
<li class="">Higher plans include more features and sometimes higher limits (e.g. for users).</li>
<li class="">You always pay a single monthly/yearly price. There's no overages or surprises.</li>
<li class="">2 months free when you pay for a year</li>
<li class="">Generous discounts for non-profits, students, and educational organisations<!-- -->
<ul>
<li class="">As a university student, and a former chair of a non-profit organisation, I know how useful these are!</li>
</ul>
</li>
<li class="">I'm friendly; if you want custom pricing for whatever reason, give me a shout!</li>
</ul>
<p>The detailed pricing I ended up adopting <a href="https://palform.app/#pricing" target="_blank" rel="noopener noreferrer" class="">is available on Palform's home page</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="the-future">The future<a href="https://docs.palform.app/blog/2024/08/27/secure-your-forms#the-future" class="hash-link" aria-label="Direct link to The future" title="Direct link to The future" translate="no">​</a></h2>
<p>Palform's the first (of many) side projects that I ended up loving so much that I'm bootstrapping it into a fully-fledged startup. It's been a lot of work, and I've been coding and perfecting it since March 2024. I'm excited to launch it, and really hope you can see its value!</p>
<p>There's many features <a class="" href="https://docs.palform.app/roadmap">planned for the future</a>, and I'm welcoming suggestions. I want to create a form-builder that's browser-first, privacy-first, and as ethically managed as possible. I'm really excited to see many similar tools spring up (e.g. <a href="https://plausible.io/" target="_blank" rel="noopener noreferrer" class="">Plausible</a>), and I think it's cool to be a part of a European "privacy revolution".</p>
<blockquote>
<p>Palform is developed in the UK and hosted on <a href="https://www.scaleway.com/" target="_blank" rel="noopener noreferrer" class="">Scaleway</a> servers located exclusively in the EU. It's fully GDPR-compliant and handles minimal data. There's no spyware on our websites.</p>
</blockquote>
<p>No matter the size of your business, <a href="https://palform.app/" target="_blank" rel="noopener noreferrer" class="">encrypting your forms</a> and securing their responses has never been more important than today. Not doing so can alienate your users and trigger concerns about your commitment to their privacy. Potentially, it can even create catastrophic data breaches. The good news: it's really easy!</p>
<p>To conclude, please be careful when choosing a form builder. Shiny flashy features are nice, but consider the potential implications of the information you're collecting being leaked or stolen. <em>Many</em> forms collect extremely sensitive personal information, and this needs to be stored responsibly. Palform makes it easy, and even reduces the amount of time you spend complying with the GDPR.</p>
<h2 class="anchor anchorTargetStickyNavbar__jMZ" id="try-out-palform">Try out Palform<a href="https://docs.palform.app/blog/2024/08/27/secure-your-forms#try-out-palform" class="hash-link" aria-label="Direct link to Try out Palform" title="Direct link to Try out Palform" translate="no">​</a></h2>
<p>You can try it out for <strong>$0/month</strong> with unlimited responses, and upgrade to our low-cost plans only as and when you need.</p>
<p>Get started <a href="https://palform.app/" target="_blank" rel="noopener noreferrer" class="">on our home page</a>.</p>
<blockquote>
<p>Thanks for reading! If you have any questions or comments, please email me personally at <a href="mailto:pal@palform.app" target="_blank" rel="noopener noreferrer" class="">pal@palform.app</a>.</p>
</blockquote>]]></content:encoded>
        </item>
    </channel>
</rss>