In the browser, not in a cookie
A cookie banner is rarely a sign of particular care; more often it signals that a website wants to know more about its visitors than it needs in order to work. The duty to obtain consent does not depend on the technology but on the purpose. If all you want is a good user experience, localStorage serves you better than a cookie, because the data stays in the browser instead of travelling to the server with every request.
What a cookie actually does
A cookie is a small snippet of text that a server hands to the browser and that the browser remembers for that domain. The decisive part happens afterwards: the browser sends the cookie back on its own with every further request to the same domain, without the page or the user having to do anything. That applies to the page request itself just as much as to every image, every script and every API call.
This is exactly the purpose the cookie was invented for. HTTP is stateless, every request stands on its own, and without such a marker a server would not know that the third request comes from the same person as the first. For a login that is indispensable, because the server has to recognise with every click who is currently signed in.
Data you never meant to send
Because the sending happens automatically, everything in a cookie travels over the wire with every request, regardless of whether the server needs it at that moment. On the way it passes load balancers, CDNs and proxies, and depending on their configuration it ends up in their logs. What was meant as a harmless setting for the interface thus becomes, in passing, data that is processed in several places.
The mechanism reaches even further when a page embeds content from other domains, such as a tracking pixel, an analytics script or an embedded button. These domains may set cookies too and get them back with every request, on every website that embeds the same service. Many individual visits thus add up to a profile across sites, and that is what third-party cookies are mostly used for in practice.
The banner depends on the purpose, not the technology
In Germany, the consent requirement behind every cookie banner is set out in Section 25 of the TDDDG, formerly the TTDSG, which implements the EU ePrivacy Directive. The law does not talk about cookies at all, but generally about storing information on the user’s device and accessing it. It is technology-neutral, so the same standard applies to localStorage when a page uses it for tracking.
What matters is the exemption in paragraph 2: no consent is needed if the storage is strictly necessary to provide a service the user has explicitly asked for. This covers the language selection, the session of a login or the shopping basket, which is why none of these cookies needs a banner. This website, too, sets exactly two cookies, one for the chosen language and a short-lived one that carries the success message after a form is submitted, and both are purely functional.
This leads to a way of reading banners that pays off in everyday life. A cookie banner does not appear because a website uses cookies, but because it wants to collect information for purposes that go beyond what the visitor is doing right now, typically audience measurement, advertising or profiling. Anyone annoyed by a banner therefore asks the better question if they do not ask about the technology, but why the operator needs this information in the first place and what happens to it, because the page almost never needs it to work.
localStorage: data that stays in the browser
For everything that is only meant to make the interface more pleasant, there has long been a better place to keep it. localStorage is a store in the browser that every website can use for its own domain and in which data remains until the page or the user deletes it again. The difference from a cookie lies in a single but essential point: the browser never sends the contents of localStorage to the server on its own.
What is stored there therefore only leaves the computer if the page deliberately puts it into a request for a specific purpose. That reverses the direction of the decision: instead of everything travelling along by default and someone having to actively decide to leave it out, only what is actually needed at that moment is transmitted. This is exactly what the GDPR demands with the principle of data minimisation and with data protection by design, and here it follows naturally from the architecture.
An example: our contact form
What this looks like in practice can be seen in the contact form on this website. The setting on the mixing desk, a draft you have started and the contact channel you used last are kept in your browser’s localStorage, so reloading the page or switching language loses nothing. These details only reach the server when you explicitly submit the form, and then exactly once, as the content of your request.
The history of your previous messages, which the form shows again on every visit, also comes from localStorage and not from the server. To show it, the website neither has to create an account nor fetch your earlier requests from the server, and no confirmation email is needed either, because your browser itself keeps track of what you wrote to us. This local copy stays tied to this one browser instance, it does not appear on any other device, and one click on “Clear local history” removes it completely.
That does not mean nothing reaches us. As soon as you submit the form, our server receives your message, your contact channel and the mixing desk setting, processes them and forwards them to Slack, which we use internally to handle requests. How this works in detail and how long the data stays there is described in our privacy policy. The difference is that only this one, explicitly submitted request is transmitted, while the draft, the preferences and the display of your history stay with you, so anything that does not strictly have to be transmitted is not transmitted.
What this means for your product
For every product of your own, the same quick check is worth doing for every new value before it ends up in a cookie. If the server needs this value with every request, like a session ID or the language, it belongs in a cookie. If only the interface needs it, such as a sort order, a collapsed panel, a draft or a preference, it belongs in localStorage, where it follows no one over the wire.
This distinction costs hardly any effort in development, but it pays off in several places. Every value that does not reach the server appears in no log, does not have to be listed in any record of processing activities and cannot leak in a security incident. Data protection then does not arise as a chore at the end of a project, but as a property of a product that collects only what it really needs from the start.
Frequently asked questions
Is this article legal advice?
No. We discuss the legal situation from a technical perspective, so you can judge what it means for running your product. For a binding assessment of your individual case, please consult a lawyer.
Does localStorage not need a cookie banner?
That depends on the purpose, not the technology. Section 25 TDDDG applies to any storage in the browser, including localStorage. If the storage only serves a service the user explicitly uses, such as a draft or a preference, no consent is needed. If localStorage is used for tracking, however, it needs consent just as a cookie does.
Which cookies are allowed without consent?
Those that are strictly necessary for a service the user has explicitly asked for to work. Typical examples are the session ID of a login, the language selection or a shopping basket. Audience measurement, advertising and profiling are not among them.
Why is a cookie more sensitive under data protection law than localStorage?
Because the browser automatically sends a cookie with every request to the domain, even when the server does not need the value. On the way it passes load balancers, CDNs and logs. The contents of localStorage, on the other hand, only leave the browser when the page deliberately puts them into a request.
When does a value belong in a cookie and when in localStorage?
If the server needs the value with every request, such as a session ID or the language, a cookie is right. If only the interface needs it, such as a sort order, a draft or a preference, localStorage is the choice that collects less data.
What does the contact form on this website store?
Your browser’s localStorage holds the mixing desk setting, a draft you have started, the contact channel you used last and the history of your sent messages. “Clear local history” removes this local copy completely. The details only reach the server when you submit the form; we then process the request and forward it to Slack, as described in our privacy policy.
Related topics
Why “we scan after the git commit” is not enough for supply chain security
A compromised npm package does not become dangerous when it lands in the repository, but the moment a developer installs it locally. Anyone who takes the supply chain seriously should therefore not ask “Did we scan?” but “Can we determine our blast radius within minutes?”, and that is an organisational question, not merely a tooling one.
Read more →The best policy is useless if it sits in a folder
Security and internal rules are often treated like a document: written once, filed, ticked off. But a policy does not become effective by existing; it becomes effective when its knowledge is within reach at the decisive moment. A real-life reporting odyssey shows how quickly even people who want to help run into a dead end, and why knowledge of internal rules belongs where the work actually happens.
Read more →