EmailTimer.App

Where recipient data goes when a personalized image renders

By Danish Mohammed, founder. 8 min read

A personalized image request carries whatever values were signed into its address, plus what every web request carries: a network address, often Apple’s or Google’s proxy rather than the person’s, and a user agent. EmailTimer.App draws the values into pixels, caches the finished image on its server for up to an hour, and writes one log line with the address. What it stores for longer is counts, not people. The server’s country is not published, and the data processing addendum says it is named on request.

This is the data chapter of choosing a dynamic image and countdown timer vendor for an enterprise email programme, and it sits beside what a security review asks an email image service, which carries the documents a reviewer signs off. Here the question is narrower: follow one open from the inbox to the database, and say what each hop sees and keeps.

Every statement below was checked against the code on 23 September 2026. Where the published documents promise something different from the code, both are given.

Two ways a value reaches the image

The choice between them decides most of what follows, so it comes first.

Values signed into the address. Your team calls the API with a first name, a points balance or a coupon code, and gets back an address with those values in its query string, covered by the signature so nobody can edit them. The value travels with the email. It is in the HTML you sent, in your sending platform’s logs, and in every cache and proxy the request passes through.

A recipient token. You upload a list, every row gets an opaque token, and the signed address carries only r= and the token. The name and the other columns never leave the server: the image service looks them up by token when it draws. This is the setup to choose when personal data in query strings is a problem for your review, and it needs the Growth plan or above, as pricing lists.

Either way, the value leaves as pixels.

A cart reminder reading Hi there, your cart is still here, beside a countdown at 24 hours, 00 minutes, 00 seconds
No value in the request: the design's own fallback word, "there".
The same cart reminder reading Hi Priya, your cart is still here, beside the same countdown
first_name=Priya in the request: the name is now part of the picture, and of every cached copy of it.

Both are renders from the product’s own engine, with a made-up name. The second one is the reason caching is a data question at all: once rendered, the image is personal data in its own right, and it sits wherever a copy of it is kept.

One open, hop by hop

What each hop sees and keeps for one personalized image request Six hops from top to bottom. The sent email and your sending platform see the full signed address and keep it in the HTML and the send logs. The mail client or its image proxy sees the address and keeps its own copy of the image for an unpublished time. Cloudflare sees the address, the network address, the user agent and the country, and caches the image for as long as the headers allow, 30 seconds for a live countdown and up to a week for a static image. The image service sees the address, the user agent and the forwarded network address, writes one log line with the signed values scrubbed out of the address, and holds network addresses in memory for rate limiting, logging only a keyed tag when it refuses a request. Redis on the same server keeps the rendered personalized image for up to an hour and a recipient record by token for two years or until the list is deleted. Postgres keeps daily counts with no recipient identifier for 450 days and failure rows without a user agent, country or token for 30 days, and backups are kept 30 days. SEES KEEPS The email, and your sending platform The whole signed address, with any values or the token in it The HTML you sent, and your send logs. Yours, not ours Mail client or its image proxy The address. Gmail and Apple fetch through proxies of their own Its own copy of the image, for a time neither Google nor Apple publishes Cloudflare Proxy today. Worker when routed The address, the network address, the user agent, the country The image, as long as headers allow: 30 seconds live, up to a week static Image service One server The address, the user agent, the forwarded network address One log line per request, values scrubbed. No network address, only a keyed tag Redis Same server The rendered image, and the recipient record for a token Personalized image: up to an hour. Token record: 2 years, or until deleted Postgres, and backups Same server, backups in R2 A count per open. No name, token, network address or user agent Daily counts: 450 days. Failure rows: 30 days. Backups: 30 days
Traced through apps/edge, apps/img, apps/jobs and packages/db on 23 September 2026.

The mail client and its proxy

Before the request reaches anybody we run, it passes through the recipient’s own mail provider. Gmail fetches images through Google’s image proxy, so the network address we receive is Google’s. Apple Mail with Mail Privacy Protection fetches at delivery, through Apple’s relay. Both keep copies of the image for as long as they choose, and neither publishes the lifetime. That is true of every image in every email, from any vendor.

Cloudflare, today and after the edge route

Cloudflare is named in annex 2 of the data processing addendum as the sub-processor that sees image requests, “including URL merge values, IP address and user agent”. Today it is the proxy and cache in front of the server. It keeps a rendered image for as long as the headers allow a shared cache to: 30 seconds for a live countdown, a week for an expired one or a static personalized image. A template with a country or device rule tells shared caches to keep nothing, so one country’s image is never served to another.

The edge Worker is deployed and its route is not live yet. When it is, it adds one copy of its own: a last-known-good render, kept a day by default and up to 30 days, served only when the server fails. When the image service is down explains what that copy is for. The Worker forwards the user agent, the recipient’s network address and the country to the server, and drops cookies.

The image service

The service reads the address, verifies the signature, draws the image and answers. On the way it writes one log line per request. That line holds the address with every signed value replaced, keeping only the path and the product’s own identifiers, so a first name or a coupon signed into the address does not reach the service log. It carries no network address and no user agent. Before 23 September 2026 the line held the full address, query string included, and the connection’s network address.

The recipient’s network address is used for one thing, a per-address rate limit, and it lives in process memory. When that limit refuses a request, the warning line carries a short tag in place of the address, keyed with a random value the service never writes down, so the tag cannot be turned back into the address. How long the log lines are kept is not stated in the privacy policy, so ask for it in writing if your review needs a number. The addendum does list “receiving and logging image fetch requests” as part of the processing.

The code can also send the address of a failed request to an error tracker. None is configured in the sub-processor list today, and adding one would need the 30 days’ notice the addendum promises.

Redis, on the same server

A personalized image is kept for one hour after it is drawn, so a recipient who opens twice is not drawn twice. A second cache keeps the finished animation for 90 seconds. A recipient record looked up by token is kept for two years, or removed as soon as you delete the list. A timer that starts at each recipient’s first open keeps a SHA-256 hash of the address and the time, for the timer’s duration plus 30 days.

Postgres, and the backups

This is where the long-lived records are, and they hold very little. Each open becomes one increment in a daily total per workspace, template and email client family. The totals carry no recipient identifier and are pruned after 450 days. A request that ended in the service card becomes one diagnostic row, kept 30 days, with the template and the reason and nothing about the recipient.

Until 23 September 2026 the privacy policy described a fuller per-request row, with the user agent, the country and the recipient token in it. The table has those columns, but the code that writes it leaves all three empty, on purpose, and writes rows only for failures. The policy (version 1.3) and the addendum (version 1.2) were corrected that day to describe what the code does, so the documents and the product now agree.

Recipient lists you upload are the exception, because they are yours to keep: the rows stay until you delete the list or the workspace. Database backups are kept 30 days, which is the longest tail on any deletion.

Where it is, and who else sees it

Where it is, and who else sees it
Where Who runs it Country Holds
One virtual private server Server hosting, named in annex 2 Not published. Named on request The image service, Redis and Postgres
Cloudflare network Cloudflare, Inc. United States, global network The proxy and cache for image requests
Cloudflare R2 Cloudflare, Inc. United States, global network Published templates, uploaded images, fonts, database backups

Annex 2 says it plainly: where a row does not name a country, “we have not published one yet and will name it on request”. If your data protection officer needs the server’s country in writing, ask before signing, not after. Transfers out of your region use the European Commission’s standard contractual clauses, the UK addendum to them, or section 16 of India’s Digital Personal Data Protection Act 2023, whichever applies.

Your role and ours follow Article 28 of the GDPR: you are the controller for your recipients’ data, and we process it on your instructions. No cookies are set on recipients. Nothing profiles them, enriches them, resells them, or trains a model on them.

Questions and answers

Is the recipient’s IP address stored?

Not in any database. The request carries one, and for many opens it belongs to Apple’s or Google’s proxy. The service uses it for a per-address rate limit held in memory. When that limit refuses a request, the log line carries a short keyed tag in place of it, which cannot be turned back into the address. The ordinary log line carries no network address at all.

Where is the server?

The server’s country is not published. Annex 2 of the addendum says it will be named on request, so ask at privacy@emailtimer.app before your review closes.

Can we keep personal data out of the image address entirely?

Yes, with recipient tokens. Upload the list, and the signed address carries an opaque token instead of any value. The values are then held on the server, in Postgres and in Redis, and deleting the list removes both.

What happens to a rendered image after a deletion request?

Deleting a recipient list removes its rows at once and queues the removal of the cached copies. A rendered image in our cache expires within the hour. Copies already held by a mail provider’s proxy or a recipient’s device are outside anybody’s reach, ours included.

Sources

Related

Put a countdown in the campaign you are writing now

The free plan covers 5,000 opens a month with no card. Starter is $19 a month for 250,000.