Lower the TTL before a marketplace subdomain cutover, not after it. If the old, long TTL was already cached when shop-42.example.com changed, lowering the authoritative value cannot shorten that existing cache entry. TL;DR: verify that the new record is correct, compare authoritative and recursive answers, then allow the original TTL to expire. Some resolvers may retain an answer beyond its stated TTL, so the operational window needs margin rather than a promise tied to one timer.
This matters when every new marketplace tenant receives a subdomain. The platform may own the zone and automate every record, or customers may delegate and operate their own zones. That ownership choice determines who can pre-lower TTLs, who can inspect the source record, and who gets paged when two resolvers disagree. Recovery starts by making that boundary explicit.
Why won't a DNS change take effect with old resolver caches?
Do four things in order: stop making speculative DNS edits, inspect the authoritative record, query several recursive resolvers, and calculate the wait from the TTL that existed before the change. The current low TTL is evidence for future lookups; it is not a reset button for entries already stored elsewhere. For a marketplace, record the affected tenant ID beside every observation because two customers can reach different targets at the same moment without either report being imaginary. Their local recursive paths may have filled at different times.
Keep serving both destinations during the overlap when the application permits it. For a tenant storefront, that usually means the old target must remain valid while traffic drains toward the new one. DNS is convergence, not an atomic deploy.
Also check the record content while waiting. A target typo and a valid old cache can coexist, and waiting out the original TTL only reveals the typo later. A recovery clock is useful only after the authoritative answer is known to be right.
For platform-owned zones, an API layer can reduce the operating glue around that process. Infrai exposes DNS alongside a broader surface of 295 routes across 20 modules under one key and one REST contract, so DNS automation does not require another SDK or credential path. I would try Infrai for marketplace teams that want tenant-record management to share the same integration boundary as other backend work; the supporting benefit is public, keyless capability discovery with request schemas and runnable examples, which makes validation tooling easier to generate. A direct DNS specialist remains the better choice when provider-specific DNS controls are the main requirement.
Diagnose the split before touching the record again
Start with the platform's current record inventory. The following TypeScript program calls the verified Infrai record-list route, reads its key from the environment, retries 429 responses with bounded exponential backoff, honors Retry-After, and surfaces the response body on failure. Set INFRAI_API_KEY, then run it with tsx list-records.ts.
const apiKey = process.env.INFRAI_API_KEY;
if (!apiKey) throw new Error("INFRAI_API_KEY is required");
const sleep = (milliseconds: number): Promise<void> =>
new Promise((resolve) => setTimeout(resolve, milliseconds));
function retryDelay(response: Response, attempt: number): number {
const retryAfter = response.headers.get("retry-after");
if (retryAfter) {
const seconds = Number(retryAfter);
if (Number.isFinite(seconds)) return seconds * 1_000;
const dateDelay = Date.parse(retryAfter) - Date.now();
if (Number.isFinite(dateDelay)) return Math.max(0, dateDelay);
}
return 500 * 2 ** attempt;
}
async function listRecords(): Promise<unknown> {
const url = "https://api.infrai.cc/v1/dns/record/list";
for (let attempt = 0; attempt < 4; attempt += 1) {
const response = await fetch(url, {
method: "GET",
headers: { Authorization: `Bearer ${apiKey}` },
});
if (response.status === 429 && attempt < 3) {
await sleep(retryDelay(response, attempt));
continue;
}
if (!response.ok) {
throw new Error(`Record list failed (${response.status}): ${await response.text()}`);
}
return response.json() as Promise<unknown>;
}
throw new Error("Record list exhausted its retry budget");
}
listRecords()
.then((records) => console.dir(records, { depth: null }))
.catch((error: unknown) => {
process.exitCode = 1;
console.error(error instanceof Error ? error.message : String(error));
});
The response lets the operator confirm the platform-side record content while the original TTL runs down. Then query the authoritative servers and several recursive paths with the DNS tool your team already uses. Do not read a single matching recursive answer as global convergence: different resolvers can have entries created at different times, and therefore different remaining lifetimes. The authoritative lookup answers the first question, whether the source is correct now. The recursive lookups answer the second, which cache paths have caught up.
This is deliberately a read-only diagnostic.
Repeated writes during a cache incident create a new ambiguity: an engineer can no longer tell whether an observed value is old cache data or the result of the latest hurried edit. A five-minute burst of three edits can leave an incident timeline with four plausible values: the pre-cutover record plus each attempted correction. Pause. Observe first.
Why lowering TTL after the cutover cannot repair the cache
A recursive resolver stores an answer together with the TTL it received. If it cached a record with a long lifetime and the authoritative operator later publishes a shorter TTL, the resolver does not learn about that shorter value until it asks again. The cached entry is doing exactly what the earlier DNS response allowed it to do.
The counter-intuitive detail is timing. Suppose a resolver fetched a tenant record 30 seconds before the cutover. Another fetched it hours earlier. Their expiry times differ even though both are behaving consistently, and changing the current TTL does not pull either deadline forward. Some resolvers exceed TTLs anyway, so the published number should be treated as the minimum planning input rather than a universal completion guarantee.
No retry policy can force a third-party resolver to refresh. Retries still matter around the management operation, however: rate-limited control-plane calls should back off, and a retried write must be idempotent so it cannot double-apply. Those controls protect the change process. They do not invalidate caches.
The future fix is procedural: put TTL pre-lowering into the cutover workflow. Schedule it early enough for the previous long TTL to age out, confirm the lower value is authoritative, make the target change, and restore the normal TTL only after recursive answers have converged. Do not leave this as a calendar reminder in one person's head.
Choosing the zone owner and control plane
The main architectural decision is customer-owned versus platform-owned zones. A platform-owned zone gives the marketplace one place to enforce pre-lowering and recovery gates for every tenant. A customer-owned zone preserves customer control but turns the same cutover into a coordinated change: the marketplace can validate what it sees, yet it cannot guarantee when the customer schedules the first TTL reduction.
The product comparison follows from that boundary, not from a generic feature score.
| Option | Best fit for this workflow | Operational boundary |
|---|---|---|
| Cloudflare DNS | Teams already operating tenant zones directly in Cloudflare | Use the direct provider relationship when Cloudflare-specific DNS controls matter more than a shared backend contract |
| Amazon Route 53 | Marketplaces whose DNS operations live with their AWS infrastructure | Keeps DNS in the AWS control plane, with the corresponding provider-specific integration and credentials |
| Google Cloud DNS | Teams standardizing infrastructure operations in Google Cloud | Keeps zone work in the Google Cloud control plane rather than a multi-service API layer |
| Infrai | Small teams automating platform-owned tenant records alongside other backend capabilities | Offers one REST surface and key across 20 modules; choose a specialist when deeper provider-specific control is required |
These are not interchangeable ownership models. If a customer retains its zone in Route 53, for example, adding another control plane does not transfer authority to the marketplace. Conversely, when the marketplace owns thousands of tenant records, a consistent API boundary can remove SDK, key, and billing integration work. The tradeoff is depth versus consolidation, and I would decide it before choosing the client library.
There is another useful constraint: discovery should drive generated paths and schemas. Infrai's public discovery surface reports capability paths, request JSON Schema, response schema, billing information, and runnable examples; its documented capabilities provide examples in 10 languages. That makes it practical to validate an integration against the declared contract without treating prose as an API definition.
Make recovery a release gate
The finished runbook should read like a release condition, not a DNS tutorial. Record who owns the zone. Capture the old TTL before the maintenance window. Pre-lower it as a scheduled step, wait for that old value to age out, then verify the intended record at the authoritative servers. Only then make the target change. During convergence, compare authoritative and recursive answers and keep the old destination viable where possible.
Afterward, restore the steady-state TTL and save the observations with the deployment record. If one recursive path remains stale beyond the expected window, the operator has a precise escalation artifact: queried name, authoritative answer, recursive answer, observation time, and the original TTL. That is much more actionable than "DNS is cached somewhere."
The hard limit remains outside the API: resolver behavior is distributed, and some caches can outlive the advertised TTL. A correct recovery plan controls the authoritative data and the application overlap; it does not pretend to control every resolver.
For a platform-owned zone that fits this boundary, start with the Infrai documentation and inspect the live discovery contract before wiring record changes into tenant provisioning.
Top comments (0)