A consent preference keeper on AWS for a few dollars a month
Marketing consent goes wrong in small businesses in a specific and expensive way. There are four systems that can send something — the newsletter tool, the e-commerce platform, the booking system, somebody’s mail merge — and each holds its own opinion about who is subscribed. Somebody unsubscribes from one and keeps hearing from two others. This post walks through a small system that gives all four the same answer.

Key takeaways
- One authoritative record, and every sending system asks it rather than holding an opinion.
- Every change is an immutable event with its evidence, not an updated flag.
- Consent is per purpose. Agreeing to order updates is not agreeing to a newsletter.
- A withdrawal takes effect immediately and is pushed to every downstream copy.
- Designed on AWS for about $2 a month.
The whole system on one page
Before any code, here is the shape of what we are designing.
- App integration
- Management
- Analytics
- Front-end & mobile
- People
Events, not a flag
A boolean on a customer record answers what is true now and destroys everything about how it became true. That is fine until somebody asks why they received an email, which in this domain is not a support question but a regulatory one, and the answer has to be specific: on this date, through this form, with this wording, they agreed to this.
So every change is an append-only event carrying its evidence: the source, the exact wording shown, the page, the timestamp and whatever identifier proves it was them. The current state is computed from the events rather than stored, which means the two can never disagree.
What runs (the inside)
- The event log. Append-only, one row per consent or withdrawal, with the evidence attached. Part 2 covers what evidence has to be captured for it to be worth anything.
- The resolver. Answers one question — may we send this purpose to this person — from the events, with a heavy cache because it is asked constantly. Part 3.
- The propagator. A withdrawal is only real when every system that could send knows about it. Part 4 is about pushing that out and, more importantly, verifying it arrived.
One withdrawal, end to end
- Machine learning
- Networking
- Management
- Analytics
In plain words
Somebody clicks unsubscribe in a newsletter. The link records a withdrawal event for the marketing purpose, with the campaign it came from, the timestamp and the signed token that proves it was that recipient. Their state for marketing becomes withdrawn immediately.
The propagator then pushes that to the four systems that hold their own lists: the newsletter tool, the e-commerce platform, the booking system and the CRM. Three confirm within seconds. The fourth — the booking system, whose API is slow — is retried and confirms four minutes later. All four are recorded as confirmed with timestamps.
Fourteen months later that person emails asking why they were contacted about a special offer. The answer takes about ten seconds to produce: they withdrew from marketing on the 7th of August 2026, the send in question was an order-related notification under a different purpose they have not withdrawn from, and here is the exact wording they agreed to when they placed the order. That is a completely different conversation from the one that starts with somebody checking a flag.
Design rules that shaped every decision
- Events, never a flag. The current state is computed and the history is the point.
- Consent is per purpose. Order updates, marketing and service messages are different questions.
- Never infer consent. A purchase is not agreement to a newsletter, however convenient that would be.
- Withdrawal is immediate and pushed, and the push is verified rather than assumed.
- Unreachable means do not send. A resolver that is down must fail closed.
- The evidence is captured at the moment, not reconstructed later. Wording changes.
Why this shape
Consent management platforms exist and are good, and for a business of any size they are usually the right answer. The reason to build a small one is that most small businesses will not buy one and will instead keep four independent lists, which produces the specific failure this system exists to prevent: somebody unsubscribing and still hearing from you.
So the design is deliberately small enough to actually get built: one table of events, one question, and a push. It does not manage cookie consent, it does not produce a compliance dashboard, and it does not try to be a customer data platform. It answers one question consistently and keeps the evidence.
The next four posts walk through each piece: how an event is recorded, how the answer is resolved, how a withdrawal propagates, and what the evidence has to look like. One diagram per post, a cost breakdown, and an engineering reference at the end.
All posts