Author: onetwothreeadmin

  • WordPress CDN cache purge: when stale pages linger after publish

    WordPress CDN cache purge: when stale pages linger after publish

    WordPress CDN cache purge: when stale pages linger after publish
    Photo by Szabo Viktor on Unsplash

    You update a post, hit Publish, and check the live page—but the old version is still there. You clear your browser cache. Still stale. You wait five minutes. Still wrong.

    The culprit is usually your CDN’s edge cache, and the purge signal your WordPress site sent either never arrived, arrived too late, or targeted the wrong URL variant.

    Here’s how CDN cache invalidation actually works, where the automation breaks, and what to verify when pages stay stuck.

    How WordPress tells a CDN to purge

    When you publish or update a post, most WordPress caching plugins send a purge request to your CDN. The request typically targets:

    • The post or page URL itself
    • The homepage
    • Any archive pages (category, tag, author) that list the post
    • RSS feeds

    Popular plugins like WP Rocket, W3 Total Cache, and LiteSpeed Cache include CDN purge integrations for Cloudflare, StackPath, KeyCDN, and others. Each uses the CDN’s API to issue a cache invalidation command.

    The CDN then propagates that purge across its edge nodes. Depending on the provider and purge method, this can take anywhere from a few seconds to several minutes.

    Where purge requests fail

    The most common failure points:

    API credentials expired or misconfigured. If your plugin is using an outdated API token, the purge request returns a 401 or 403 error—but WordPress doesn’t surface that to you. Check your CDN integration settings and regenerate tokens if you’ve rotated passwords or switched accounts.

    URL mismatch between WordPress and the CDN. If your WordPress site uses http:// internally but your CDN caches https:// URLs, or if you’ve changed your permalink structure without flushing the CDN, purge requests may target URLs that don’t match what’s actually cached. Cloudflare’s API, for example, treats example.com/post/ and example.com/post (with and without trailing slash) as distinct cache keys unless you’ve set a page rule to normalize them.

    Partial purge vs. full purge. Many plugins default to purging only the updated post and homepage to avoid rate limits. If your post appears on a paginated archive (e.g., page 2 of a category), that archive page may remain cached with the old excerpt or publish date. Some CDNs charge per purge request or throttle bulk invalidations, so plugins err on the side of conservative purging.

    CDN caching HTML despite cache-control headers. If your CDN is set to ignore origin cache headers and enforce its own TTL, purge requests may succeed but the CDN repopulates the cache immediately from a stale upstream layer (like Varnish or Redis object cache on your host). Check your CDN’s cache rules to ensure it respects Cache-Control: no-cache or must-revalidate directives for dynamic pages.

    What to check first

    When a page won’t update:

    Confirm the CDN is the bottleneck. Bypass the CDN by hitting your origin server directly (use your host’s IP or a hosts-file override). If the page is current at origin but stale through the CDN, the purge failed.

    Check the plugin’s purge log. WP Rocket and LiteSpeed Cache log purge events in their debug modes. Enable logging, update the post again, and review whether the plugin attempted a purge and what response it received. Missing API errors here are a smoking gun.

    Verify which URLs were purged. Most CDN dashboards (Cloudflare’s under Caching → Configuration → Purge Cache history, checked November 2026) show recent purge requests. Compare the purged URLs to the actual cached URLs. If you see /blog/post-name/ purged but your CDN cached /blog/post-name, trailing-slash normalization is broken.

    Test with a manual full purge. Log into your CDN dashboard and purge everything. If the page updates immediately, the issue is with selective purging logic—either the plugin isn’t targeting the right URLs, or your CDN’s partial purge propagation is slow.

    A non-obvious fix

    If you’re using Cloudflare with a page rule that caches everything, double-check the Cache Level setting. Cloudflare’s Ignore Query String level treats example.com/post?v=123 and example.com/post as the same cache object, which can cause purge misses if your theme or plugin appends query strings for versioning. Switch to Standard or add an explicit purge for query-string variants.

    For hosts running Varnish or Nginx FastCGI cache in front of WordPress, coordinate purges at both layers. Your CDN plugin may purge the CDN edge but leave Varnish’s copy intact; the CDN refetches stale HTML from Varnish, and you’re back where you started. Tools like Varnish HTTP Purge (checked via the WordPress plugin directory, November 2026) can integrate with your CDN plugin to purge both simultaneously.

    Cache invalidation remains one of the hardest problems in distributed systems. When it breaks, start at the origin, trace the purge path, and confirm every hop actually cleared.

    Hit reply if you’ve found a CDN purge edge case we didn’t cover—we’ll feature operator solutions in a future issue.

  • Traffic source tagging breaks when redirect chains rewrite parameters

    You spend twenty minutes building a campaign URL with source, medium, campaign, term, and content tags. You paste it into a social scheduler, send it through a link shortener, and watch the clicks roll in. Then you open your analytics dashboard and see half the traffic attributed to “direct” or a generic referrer that has nothing to do with your campaign.

    The problem isn’t your tracking setup—it’s the redirect chain between your tagged link and the final destination. Every hop is an opportunity for parameters to get stripped, overwritten, or malformed.

    Where parameters disappear in the chain

    Most link shorteners preserve query parameters by default. Bit.ly, TinyURL, and Rebrandly all append your UTM tags to the destination URL when someone clicks. But not all redirects behave the same way.

    If your destination URL is itself a redirect—say, a landing-page builder that forwards to a Stripe checkout, or a ConvertKit form that redirects to a thank-you page—each step in that chain can rewrite the URL. Some platforms strip all query parameters on redirect. Others preserve them but only if the destination field includes a placeholder like ?original_params or {query}.

    CDN-level redirects are another common failure point. If you’ve set up a redirect rule in Cloudflare, Fastly, or your WordPress host’s edge config, check whether it’s configured to forward query strings. Most dashboards default to “no” unless you explicitly enable passthrough.

    Which tools rewrite tags and which preserve them

    Social media platforms handle UTM parameters inconsistently. LinkedIn’s link wrapper preserves them. Facebook’s l.facebook.com redirect usually does too, but if your link triggers a security interstitial or a “leaving Facebook” warning, parameters can get lost in the process.

    Email service providers are generally safe. MailerLite, Brevo, and Postmark all preserve query parameters in click-tracking redirects, though you should confirm that your click-tracking domain is configured correctly—mismatched SSL or DNS can cause the ESP to fall back to a generic redirect that doesn’t pass parameters.

    Landing-page builders vary. Carrd preserves parameters by default. Unbounce does too, but only if you’ve mapped the destination URL as a dynamic field. Webflow’s form-redirect action strips them unless you add a query-string rule in the redirect settings (checked November 2026, per Webflow’s redirect documentation).

    How to test your redirect chain before you publish

    Paste your full tagged URL into a browser’s private window. Before you hit enter, open the browser’s network inspector (right-click, “Inspect,” then click the “Network” tab). Load the URL and watch the waterfall. Each redirect will appear as a separate request. Click into each one and check the “Headers” section for the Location: field. If your parameters are missing from any step, that’s where the chain breaks.

    If you’re using a link shortener, check whether it offers redirect preview. Bit.ly’s /info endpoint shows the full destination URL, including any appended parameters. Rebrandly’s dashboard shows the same under “Link Details.”

    For landing-page redirects, create a test page with a known UTM string and fire it through the funnel. If the final thank-you page or checkout URL is missing the tags, check the platform’s redirect or form-action settings. Most builders document parameter passthrough in their knowledge base, but the setting is rarely enabled by default.

    When to skip UTM tags entirely

    If your funnel includes more than two redirects, or if you’re driving traffic through a third-party platform you don’t control (app stores, marketplaces, affiliate networks), UTM tagging becomes fragile. In those cases, use a dedicated campaign parameter that your analytics tool can parse separately—like ref= or via=—and append it only to the final destination URL, not the intermediary links.

    Some operators skip URL tagging altogether and rely on referrer headers. That works for organic social and direct website links, but referrer data gets stripped when users click from HTTPS to HTTP, or when browsers enforce referrer policies like no-referrer or strict-origin. It’s not a replacement for explicit campaign tagging.

    Want more breakdowns like this? Subscribe to One Two Three Send and get operator-focused guides like this one every week—no fluff, just the mechanics that matter.

    Heads up — some links in this article are affiliate links. If you sign up through them, we may earn a small commission at no extra cost to you. We only recommend tools we use ourselves.

  • Instagram carousel posts: post count, reach delta, and save rate

    Instagram carousel posts: post count, reach delta, and save rate

    Instagram carousel posts: post count, reach delta, and save rate
    Photo by Nathana Rebouças on Unsplash

    Instagram carousels—posts with 2–10 swipeable slides—are the format most operator accounts default to. The theory: more slides mean longer dwell time, which signals quality to the algorithm, which lifts reach and saves.

    That’s true in principle. But the mechanism is more specific than most operators realise, and slide count alone doesn’t guarantee better distribution. Here’s how carousels work under the hood, when they help, and when a single image performs better.

    How Instagram ranks carousel posts

    Instagram’s public Ranking Explained page (checked November 2026) lists time spent as one of several signals the feed algorithm uses. The platform doesn’t give carousels a boost just for being carousels—it measures whether people stop scrolling, swipe through slides, and linger.

    That means a ten-slide carousel that nobody swipes past slide two will rank lower than a single-image post people pause on. The format is a tool, not a cheat code.

    Carousel posts also appear in the feed multiple times if a user didn’t swipe through all the slides on first view. Instagram confirmed this in a 2021 blog post explaining feed ranking, and the behaviour still applies in 2026: unfinished carousels can re-surface hours or days later, giving you a second impression without paying for it.

    Slide count and completion rate

    The trade-off: more slides mean lower completion rates. If you publish a ten-slide carousel, most viewers will drop off by slide four or five. Instagram doesn’t publish completion benchmarks, but every operator who checks their Insights sees the same pattern—engagement drops sharply after the first three slides.

    That’s not necessarily bad. A post that holds attention for five slides still accumulates more seconds of dwell time than a single image someone scrolls past in two. But it also means slides six through ten are doing very little work unless your hook and pacing are strong enough to keep people swiping.

    Short carousels—three to five slides—tend to balance completion rate and total time spent. You get the algorithmic benefit of multi-slide engagement without the drop-off penalty of a long deck that loses half the audience halfway through.

    Saves, shares, and carousel structure

    Instagram treats saves as a strong positive signal. A saved post is content someone wants to return to, which the algorithm interprets as high value. Carousels that function as reference material—checklists, comparison charts, step-by-step guides—tend to earn more saves than single images because they pack more utility into one post.

    But that only works if the first slide makes the value obvious. If your opening slide looks like every other text-on-gradient template, people won’t swipe. The hook has to promise something worth finishing.

    Shares follow a similar pattern. Carousels that tell a clear story or build to a punchline in the final slide get shared more than single images, but only if the narrative structure is tight. A ten-slide carousel that meanders will get fewer shares than a punchy single-image meme.

    When a single image beats a carousel

    Carousels aren’t always the right format. Single-image posts work better when:

    • The idea fits in one frame—no need to stretch it across multiple slides just to game the algorithm.
    • You’re optimising for comments, not saves. A provocative single image with a question in the caption often sparks more discussion than a carousel that asks people to swipe and comment.
    • You’re running ads. Instagram’s ad manager supports carousels, but single-image ads often convert better because there’s no friction—one image, one message, one CTA.

    The platform doesn’t penalise single-image posts. If people engage, it ranks. The format choice should match the content, not the other way around.

    What to test

    If you’re running an operator account and want to figure out whether carousels help your specific audience, test slide count and structure separately. Try:

    • Three-slide carousels vs. ten-slide carousels on the same topic, and compare completion rate in Insights.
    • Single-image posts vs. short carousels on similar themes, and track saves and shares.
    • Front-loading your strongest slide (the punchline or key insight first) vs. building to it at the end, and watch where people drop off.

    Instagram Insights shows you swipe-through rate and time spent per post. If your ten-slide carousels consistently lose half the audience by slide five, cut them to five slides and see if engagement holds.

    Carousels work when they’re built for the platform’s mechanics—clear hook, tight pacing, payoff worth finishing. Slide count is a lever, not a strategy.

    What’s working for your account—carousels or single images? Reply and let us know. And if you found this useful, subscribe below—we publish operator breakdowns like this every day.

  • AI model context windows: what fits, what gets cut, and when to chunk

    AI model context windows: what fits, what gets cut, and when to chunk

    AI model context windows: what fits, what gets cut, and when to chunk
    Photo: NASA/GSFC/Arizona State University via Wikimedia Commons (Public domain)

    Every AI model has a context window—the maximum amount of text it can process in a single request. Send too much and the model either truncates your input, returns an error, or silently drops the earliest parts of your conversation. For solo operators feeding customer emails, blog drafts, or research notes into an AI assistant, hitting that ceiling means lost context and useless output.

    Understanding how context windows work, what actually counts against them, and when to split your input saves you from re-running failed requests and wondering why the model ignored half your instructions.

    What the context window actually measures

    Context windows are measured in tokens, not characters or words. A token is roughly four characters in English, so a 128,000-token window handles around 96,000 words—but that’s a rough average. Punctuation, code, and non-English text tokenize differently.

    The window includes everything: your system prompt, the user message, any examples you provide, the model’s previous responses in the conversation, and the new response it’s generating. If you’re running a multi-turn chat, earlier exchanges eat into the budget before your latest question even arrives.

    As of November 2026, Claude offers models with context windows up to 200,000 tokens (checked November 2026). OpenAI’s GPT-4 Turbo and GPT-4o support 128,000 tokens (checked November 2026). Smaller models and older versions cap out much lower—sometimes as low as 4,096 tokens.

    When you hit the limit

    Different platforms handle overflow differently. Some models truncate silently from the beginning of the conversation, keeping only the most recent exchanges. Others return an error and refuse to process anything. A few will let you submit the request but deliver incomplete or incoherent output because critical context was dropped mid-thought.

    If you’re pasting a 15,000-word research document and a 500-word prompt into a model with an 8,000-token window, the model will never see your instructions—they’ll be cut first. The API won’t always warn you.

    Check your provider’s documentation for token-counting tools. OpenAI provides a browser-based tokenizer (checked November 2026) that shows exactly how your text gets chunked. Anthropic’s API returns token counts in the response metadata.

    Chunking strategies that preserve meaning

    When your input exceeds the window, split it intelligently rather than chopping at arbitrary character limits. Break on section headings, paragraph boundaries, or logical topic shifts—not mid-sentence.

    Process each chunk separately with the same prompt, then either concatenate the outputs or run a second pass that summarizes the individual results. For long documents, include a brief summary of earlier chunks in each subsequent request so the model maintains continuity.

    Avoid sliding-window approaches where you overlap chunks by 10–20%. They burn tokens on repetition and rarely improve output quality unless you’re doing deep semantic analysis across boundaries.

    If you’re building a retrieval-augmented generation (RAG) system, pre-filter your knowledge base so only relevant excerpts enter the context window. Embedding-based search and vector databases let you pull the five most relevant paragraphs instead of dumping entire articles into the prompt.

    What doesn’t count (and what shouldn’t)

    System prompts and fixed instructions count against the window every time, even if they never change. If you’re running the same 2,000-token system message on every request, you’ve permanently reduced your effective window by 2,000 tokens. Trim boilerplate, combine redundant examples, and move static reference material out of the prompt and into a pre-processed lookup table.

    Formatting tokens add up faster than you expect. JSON scaffolding, XML tags, and markdown syntax all consume budget. If you’re wrapping every data point in verbose markup, you’re trading tokens for structure that the model may not need.

    Model responses count toward the window in multi-turn conversations, so long assistant replies in early turns compress the space available for later exchanges. If you’re running a ten-message chat and the model wrote 1,500 tokens in message three, those tokens reduce what you can send in message eleven.

    When to pay for a bigger window

    Larger context windows cost more per token. Claude‘s extended-context models and OpenAI’s GPT-4 Turbo charge higher per-million-token rates than smaller-window alternatives. If you’re processing hundreds of requests daily, a bigger window might double your API bill without improving output.

    Use a larger window when you genuinely need the model to synthesize across many pages—legal document review, multi-file code analysis, or research summarization. Don’t default to the largest available model for single-question tasks that fit comfortably in 4,000 tokens.

    For high-volume workflows, test whether breaking a 20,000-token job into four 5,000-token chunks and using a cheaper model produces acceptable results. The cost difference often outweighs the minor quality trade-off.

    One thing to try this week: Paste your most common AI prompt into your provider’s token counter and check how much headroom you actually have. If you’re regularly within 10% of the limit, either shrink your input or switch to a model with a bigger window before you start losing context in production.

    Got a question about working with AI tools in your online business? Reply to this email—we answer reader questions every Sunday.

    Heads up — some links in this article are affiliate links. If you sign up through them, we may earn a small commission at no extra cost to you. We only recommend tools we use ourselves.

  • Newsletter open-rate benchmarks: why industry averages mislead

    Newsletter open-rate benchmarks: why industry averages mislead

    Newsletter open-rate benchmarks: why industry averages mislead
    Photo by Stephen Dawson on Unsplash

    Every quarter, email service providers and marketing blogs publish open-rate benchmarks: “SaaS newsletters average 22%,” “B2B sees 18%,” “media hits 25%.” Solo operators compare their own numbers to these figures, panic when they fall short, and chase tactics that don’t address the real problem.

    Industry benchmarks are nearly useless for individual operators because they aggregate data across lists with wildly different histories, engagement patterns, and technical configurations. A brand-new list of 500 highly-engaged subscribers will perform nothing like a three-year-old list of 50,000 where half haven’t opened in six months. Comparing your 19% open rate to a industry average of 22% tells you nothing about whether your content works or your list is healthy.

    What benchmarks hide

    Published benchmarks rarely disclose how they handle Apple Mail Privacy Protection, which pre-fetches email content and inflates open rates for some senders while masking real opens for others. A newsletter platform might report that media newsletters average 25% opens, but if 40% of that list uses Apple Mail, the real engaged-open rate could be 15% or 35%—you can’t tell from the top-line number.

    List age matters more than industry. A six-month-old list of operators who signed up for a lead magnet last week will open at 40%. A four-year-old list where you haven’t pruned inactive subscribers in two years might sit at 12%, even if both lists cover the same topic. Benchmarks don’t segment by list tenure, acquisition source, or cleanup cadence, so they flatten signal into noise.

    Engagement history compounds over time. If you’ve been sending consistently valuable content for a year, your open rate should climb as your list self-selects for people who actually want to hear from you. If you’ve been inconsistent or changed topics mid-stream, your rate will sag regardless of industry. Benchmarks assume a static audience; real lists evolve.

    What to track instead

    Compare your open rate to your own trailing average, not an industry figure. If you normally sit at 28% and this week hit 22%, investigate the subject line, send time, or whether you skipped a week and lost rhythm. If you’re steady at 19% for six months and your click rate is climbing, your open rate isn’t the problem—your subject lines might be honest rather than clickbaity, and that’s fine.

    Segment by subscriber cohort and measure each group’s trend. New subscribers (0–30 days) should open at a higher rate than your list average. If they don’t, your onboarding sequence or acquisition source is weak. Subscribers older than 180 days who haven’t opened in 90 days are dead weight; archive or re-engage them, then watch how your open rate moves when you remove that drag.

    Track click-to-open rate instead of raw opens. If 25% of people open and 8% click, your click-to-open rate is 32%—meaning nearly a third of people who opened took action. That ratio tells you whether your content delivers on the subject line’s promise. A falling open rate with a rising click-to-open rate means you’re getting better at writing for the people who care, even if fewer people care overall. That’s often a healthy sign for a maturing list.

    When benchmarks do matter

    Benchmarks become useful when you control for list age, acquisition source, and privacy configuration—and compare only to operators with similar profiles. If you run a six-month-old SaaS newsletter, acquired entirely through content upgrades, and you’re seeing 18% opens while a peer with the same profile sees 32%, then you have a real gap to investigate. But that’s not an industry benchmark; it’s a matched cohort.

    Platform-level data can surface technical issues. If Beehiiv reports that lists using custom domains see 5% higher placement rates than shared domains (checked November 2026, Beehiiv deliverability guide), that’s actionable—you’re comparing apples to apples within one platform’s infrastructure. But cross-platform averages wash out those details.

    Use benchmarks to spot outliers in your own data, not to judge performance. If your Monday sends consistently open 10 percentage points higher than Thursday sends, and industry data shows no day-of-week effect, you’ve found a scheduling advantage specific to your audience. The benchmark didn’t tell you what to do—it just confirmed your pattern isn’t universal, so you should exploit it.

    Want more on what to measure when aggregates don’t help? Reply and tell us which metric you’re struggling to interpret—we’ll cover it in a future issue. Or subscribe below if this landed in a forward.

    The real benchmark is last month

    If your open rate is climbing month-over-month, your click rate is stable or rising, and your unsubscribe rate stays below 0.5% per send, you’re doing fine—regardless of whether you’re at 15% or 35%. Industry averages can’t account for your list’s unique composition, your content’s value density, or the trust you’ve built over time. Track your own trend, segment ruthlessly, and ignore the rest.

    Heads up — some links in this article are affiliate links. If you sign up through them, we may earn a small commission at no extra cost to you. We only recommend tools we use ourselves.

  • Productivity app keyboard shortcuts: which save time, which waste it

    Productivity app keyboard shortcuts: which save time, which waste it

    Productivity app keyboard shortcuts: which save time, which waste it
    Photo by Aditya Rathod on Unsplash

    Keyboard shortcuts promise speed. Most productivity apps ship with dozens—sometimes hundreds—of key combinations designed to eliminate mouse clicks and menu hunting. But not every shortcut delivers a measurable time saving, and learning the wrong ones adds mental overhead that slows you down more than the original click ever did.

    The question isn’t whether shortcuts are useful. It’s which ones actually pay back the time you invest in forming the muscle memory, and which ones clutter your working memory without meaningful return.

    The 80/20 rule applies to shortcuts

    Most productivity apps follow the Pareto principle: a small number of shortcuts account for the majority of useful speed gains. In text editors, email clients, and project management tools, five to eight commands usually cover 80% of repetitive actions.

    For email platforms, that’s typically: archive, delete, reply, compose new, search, and navigate between messages. In task managers: new task, mark complete, navigate lists, search, and set due date. In writing apps: save, find-and-replace, bold/italic, and insert link.

    These high-frequency commands save time because you use them dozens or hundreds of times per session. A two-second saving repeated fifty times a day returns real value. A shortcut you use twice a week doesn’t.

    Where shortcuts add cognitive load instead of speed

    Multi-key combinations with modifier stacks—Ctrl+Shift+Alt+[key], for example—require deliberate recall every time. Unless you’re triggering the action constantly, you’ll pause to remember the sequence, negating any time saved over clicking a labeled button.

    Context-dependent shortcuts create similar friction. If a key does different things depending on whether you’re in a list view, detail pane, or editor mode, you’re adding decision overhead. Each use requires you to confirm your context before pressing the key, which reintroduces the hesitation shortcuts are meant to eliminate.

    Apps that reassign common system shortcuts create interference. If your task manager uses Cmd+T for something other than “new tab,” and your browser, text editor, and terminal all use Cmd+T for new tab, you’ll regularly misfire and need to undo. The mental tax of context-switching between conflicting key maps outweighs any individual shortcut’s value.

    How to audit your own shortcut use

    Most operators overestimate how many shortcuts they actually use. Here’s a practical audit:

    • Open your most-used productivity app and pull up its shortcut reference (usually under Help or Preferences).
    • Mark every shortcut you used in the last working session without looking it up.
    • Compare that list to the app’s full shortcut inventory.

    The gap between what you know and what the app offers is usually large. That gap isn’t a problem—it’s information. It tells you which actions aren’t frequent enough to justify memorisation.

    For shortcuts you want to adopt, test whether they’re faster than your current method. Time yourself completing the same task ten times with the mouse, then ten times with the shortcut. If the shortcut doesn’t save at least one second per use after the learning phase, it’s not worth the cognitive real estate.

    Which shortcuts are worth learning first

    Prioritise shortcuts that eliminate mode switching. Any command that lets you stay in a text field or composition window without reaching for the mouse compounds its value across a session. In email clients, that’s send, archive, and reply. In task apps, it’s create, complete, and move between items. In writing tools, it’s save, insert link, and search.

    Navigation shortcuts—moving between panes, tabs, or sections without clicking—deliver value if the app’s layout requires frequent movement. If your workflow keeps you in one pane 90% of the time, navigation shortcuts won’t pay back.

    Ignore customisation shortcuts (changing themes, toggling sidebars, adjusting font size) unless you adjust those settings multiple times per session. Configuration commands are low-frequency by nature; reaching for a menu once a week costs nothing.

    We’re not suggesting you avoid shortcuts entirely. We’re saying most apps offer far more than you’ll ever use productively, and the time spent memorising low-value commands is time you’re not spending on the work itself. Build your shortcut vocabulary around high-frequency actions, audit what you actually use, and ignore the rest.

    Got a productivity habit you’ve tested and want to share? Reply to this email—we read every response and pull the best operator insights into future editions.

  • Monetisation platform webhooks: when they fire and where they fail

    Monetisation platform webhooks: when they fire and where they fail

    Monetisation platform webhooks: when they fire and where they fail
    Photo by David Pupăză on Unsplash

    Most online operators rely on webhooks to automate post-purchase workflows: add a buyer to your newsletter, grant course access, send a receipt, or trigger fulfillment. Payment and subscription platforms—Stripe, Gumroad, Lemon Squeezy, Paddle—all offer them, but they don’t behave the same way.

    Webhooks are HTTP POST requests the platform sends to your server when an event occurs: a charge succeeds, a subscription renews, a refund is issued. Your endpoint receives a JSON payload, verifies it, and takes action. Simple in theory. In practice, timing windows, retry policies, and failure modes create gaps that can break your automation—and leave customers waiting.

    When webhooks actually fire

    Most platforms send a webhook immediately after an event completes on their side. Stripe fires charge.succeeded within seconds of card capture (Stripe webhooks documentation, checked November 2026). Gumroad queues its sale notification shortly after payment clears. Lemon Squeezy and Paddle follow similar patterns.

    But “immediately” isn’t instant. Network latency, platform load, and internal queueing can introduce delays. Stripe’s documentation notes that webhooks may arrive out of order if multiple events fire in quick succession—so a customer.subscription.updated event can reach your server before the customer.subscription.created that preceded it.

    For high-volume operators, this creates a design constraint: your webhook handler must be idempotent (safe to run more than once on the same event) and tolerant of out-of-order delivery. Store event IDs and check for duplicates before processing.

    Retry logic and failure windows

    When your endpoint is unreachable—server restart, DNS hiccup, deploy in progress—the platform retries. Retry schedules differ.

    Stripe retries failed webhooks for up to three days, with exponential backoff: the first retry happens after a few seconds, subsequent attempts spread over hours (Stripe retry best practices, checked November 2026). If all retries fail, the event is marked as failed in your dashboard. You can manually resend it, but there’s no automatic recovery after the window closes.

    Gumroad retries for 72 hours. Lemon Squeezy follows a similar three-day window. Paddle’s retry schedule is shorter—24 hours—and its documentation warns that events older than that cannot be replayed (Paddle webhooks overview, checked November 2026).

    This matters if you’re migrating servers, changing endpoints, or experiencing downtime. A 48-hour outage on Paddle means lost events. On Stripe, you have a narrow recovery window—but only if you notice the failure and resend manually.

    Where webhooks break silently

    The most common failure mode isn’t a hard error—it’s a silent drop. Your server returns HTTP 200 (success) too early, before the database write completes. The platform marks the webhook as delivered. Your workflow never runs.

    Always acknowledge the webhook after you’ve committed the critical action—writing the order to your database, adding the email to your list, or queueing the follow-up job. Return 200 only when the work is durable. If your server crashes mid-process, return a 5xx status so the platform retries.

    Another silent failure: signature verification bugs. Every platform signs its webhook payloads so you can confirm they’re authentic. Stripe uses HMAC-SHA256 with a signing secret; Gumroad appends a hash parameter. If your verification logic is wrong—comparing the raw body instead of the canonical form, or using the wrong secret after a key rotation—you’ll reject legitimate webhooks and never know why.

    Test your handler with the platform’s CLI tool (Stripe offers stripe listen) and confirm that replayed events trigger the same outcomes as live ones.

    Designing around webhook unreliability

    Webhooks are notifications, not the source of truth. Treat them as a prompt to check the platform’s API, not as the definitive record of what happened. When a charge.succeeded arrives, query the Stripe API for the charge object and verify its status before granting access.

    For mission-critical workflows—access provisioning, high-value purchases—add a fallback: poll the platform’s API periodically for recent transactions and reconcile against your database. If a webhook was dropped or delayed beyond the retry window, your polling job catches it within minutes or hours instead of leaving the customer stuck.

    Store the raw webhook payload in a separate table before processing it. If your automation logic changes or you discover a bug weeks later, you can replay old events from your archive without asking the platform for help.

    Webhooks are the fastest path from payment to fulfillment, but they’re not guaranteed delivery. Build your automation to survive the gaps, and you’ll spend less time manually fixing stuck orders.

    One Two Three Send covers tools, workflows, and infrastructure for online operators. Subscribe to get one focused article every morning.

  • WordPress multisite subdomain wildcards: DNS, SSL, and provisioning

    WordPress multisite in subdomain mode promises a clean architecture: every new site gets its own subdomain, and the platform handles provisioning automatically. In practice, three layers—DNS wildcards, SSL certificate issuance, and web-server routing—each introduce failure points that most operators discover only after the first user tries to access a freshly created site and sees a browser error.

    This guide walks through how wildcard subdomain provisioning actually works, where it breaks, and what to check when a new site won’t load.

    DNS wildcard records: what they match and what they don’t

    A wildcard DNS A record like *.example.com tells resolvers that any subdomain—alice.example.com, bob.example.com—should resolve to the same IP address as the multisite installation. You add this record once in your DNS provider’s control panel, pointing to your server’s public IP.

    Wildcards match only one level deep. If you need nested subdomains like project.alice.example.com, the wildcard *.example.com won’t cover it; you’d need *.alice.example.com or another arrangement. Most multisite installations stick to single-level subdomains to avoid this complexity.

    DNS propagation is usually fast—under an hour for most resolvers—but caching at the user’s ISP or device can mean stale lookups persist for the original TTL. Set a low TTL (300 or 600 seconds) on the wildcard record before launching new sites if you expect rapid iteration.

    SSL wildcard certificates: issuance, renewal, and Let’s Encrypt limits

    Once DNS resolves, the browser requests HTTPS. A wildcard certificate like *.example.com covers all first-level subdomains in a single cert. Let’s Encrypt supports wildcard issuance via DNS-01 challenge, which requires your host or control panel to programmatically update a _acme-challenge TXT record during validation (documented in the Let’s Encrypt challenge-types guide, checked November 2026).

    Not every managed WordPress host automates DNS-01. If your host uses HTTP-01 validation instead, you’ll need to request individual certificates for each subdomain, which breaks the seamless provisioning model. Check your host’s multisite documentation before committing to subdomain mode.

    Let’s Encrypt rate limits allow 50 certificates per registered domain per week (rate-limits page, checked November 2026). If you’re spinning up dozens of subsites in a short window and relying on individual HTTP-01 certs, you’ll hit the cap and new sites will serve warnings until the counter resets. Wildcard certs bypass this entirely, because one cert covers the whole namespace.

    Web-server routing: how Nginx and Apache parse Host headers

    After DNS and SSL succeed, the request reaches your web server. WordPress multisite relies on the Host header to identify which subsite the visitor wants. Nginx and Apache both support wildcard server blocks or virtual hosts, but the configuration syntax differs and misconfigurations silently fall back to the default site.

    In Nginx, a server_name directive like *.example.com matches any subdomain. If you’re using a caching layer or CDN in front of Nginx, make sure the Host header passes through unmodified; some CDNs rewrite it to the origin hostname, which breaks multisite routing.

    Apache’s ServerAlias directive accepts wildcards similarly. Both servers also respect the order of virtual-host definitions: if the wildcard block appears after a more specific block, requests may match the wrong site. Place the wildcard configuration last in your include order to ensure fallback behavior works as expected.

    Auto-provisioning failures: what to check when a new site won’t load

    When a user reports that a newly created subsite shows a certificate error, connection timeout, or default Apache page, work backwards through the stack:

    • DNS: Use dig alice.example.com or an online resolver tool to confirm the wildcard record resolves to the correct IP. If it doesn’t, check your DNS provider’s propagation status and TTL settings.
    • SSL: Check the certificate presented by the subdomain with openssl s_client -connect alice.example.com:443 -servername alice.example.com. If it’s a self-signed cert or doesn’t include the subdomain in the SAN list, your wildcard cert didn’t issue or isn’t installed correctly.
    • Web server: Review access logs for the subdomain request. If the log entry shows a 200 but the browser sees an error, caching or a CDN is serving stale content. If the log shows a 404 or no entry appears, the server block isn’t matching; review your Nginx or Apache configuration syntax.
    • WordPress: Confirm the subsite exists in the network admin dashboard and that its domain matches exactly what the user is requesting. Trailing slashes, www prefixes, and protocol mismatches all cause routing failures.

    When to avoid subdomain mode altogether

    Subdomain multisite makes sense when you want clean namespace separation and don’t mind the DNS and SSL overhead. If your hosting environment doesn’t support wildcard DNS automation or you’re on a shared host without root access to install wildcard certificates, subdirectory mode (example.com/alice) is simpler and avoids all three provisioning layers.

    Subdirectory mode also bypasses browser cookie-isolation issues: cookies set on example.com are visible to all subdirectory sites, which can simplify single sign-on but complicates multi-tenant privacy. Subdomain mode isolates cookies by default, because alice.example.com and bob.example.com are separate origins.

    Running WordPress multisite? Reply with the weirdest provisioning failure you’ve debugged—we’ll feature operator war stories in an upcoming issue.

  • Traffic source tagging: UTM limits and where they break

    Traffic source tagging: UTM limits and where they break

    Traffic source tagging: UTM limits and where they break
    Photo by 1981 Digital on Unsplash

    UTM parameters are the five query-string tags—source, medium, campaign, term, and content—that let you label inbound traffic and trace it through analytics. They work until they don’t: character limits, URL encoding collisions, and platform-specific parsing quirks can silently truncate your tags, break your links, or strip attribution entirely.

    If you’re running multiple campaigns across email, social, and paid channels, understanding where UTM tagging breaks saves you from phantom traffic sources and attribution gaps that make every dashboard untrustworthy.

    Character limits and encoding constraints

    UTM parameters are part of the query string, and query strings face two kinds of limits: browser maximums and server parsing thresholds.

    Most browsers allow URLs up to 2,000 characters (Internet Explorer historically set this floor, checked RFC 2616, November 2026). Servers often impose their own caps—Apache defaults to 8,190 bytes for the request line, and Nginx to 4,096 or 8,192 depending on configuration (Apache docs, Nginx docs, checked November 2026).

    If your UTM-tagged link plus domain and path exceeds these thresholds, the URL truncates or the server returns a 414 error. Either way, your analytics miss the visit or attribute it to “direct.”

    URL encoding adds overhead. Spaces become %20, ampersands &, and equals signs = when they appear inside parameter values. A 50-character campaign name can balloon to 70+ encoded characters. If you’re tagging links in email subject lines, social bios, or QR codes, the encoded length determines whether the link survives.

    Reserved characters and parsing collisions

    UTM values can contain letters, numbers, hyphens, and underscores without issue. Special characters—ampersands, equals signs, question marks, hash symbols—require URL encoding or they’ll confuse the query-string parser.

    An unencoded ampersand inside utm_campaign splits the value early. Say you tag a link ?utm_campaign=Spring&Summer—the parser sees two parameters: utm_campaign=Spring and an orphaned Summer with no key. Google Analytics drops the malformed tag and logs the visit under “(not set).”

    Hash symbols are worse: anything after # becomes a fragment identifier, stripped by the browser before the request reaches the server. A campaign tagged utm_campaign=Launch#2 arrives as utm_campaign=Launch, with #2 never sent.

    The fix is straightforward but easy to forget: URL-encode special characters before you publish the link. Most UTM builders—like Google’s Campaign URL Builder—handle this automatically, but manual edits or spreadsheet-generated links often skip encoding.

    Platform-specific stripping and transformation

    Some platforms rewrite or strip query parameters when users share links.

    Facebook historically stripped UTM tags from links shared in posts to prevent attribution hijacking. As of late 2026, Facebook preserves UTM parameters in organic posts but may strip or replace them in ads if you use the platform’s own URL parameters (Meta for Developers, checked November 2026).

    LinkedIn shortens shared links through lnkd.in and preserves query strings, but the redirect adds a LinkedIn tracking parameter (trk=) that some analytics tools flag as noise. Twitter—now X—does not strip UTMs, but link previews truncate visible URLs, so long parameter strings become unreadable to users even if they function.

    Email clients pose a different problem: some webmail providers—historically Yahoo, and intermittently Outlook.com—rewrite URLs for link-tracking purposes, appending their own parameters or wrapping the link in a redirect. If the rewrite fails, the original UTM tags can be lost or duplicated.

    Testing and validation workflow

    Before you launch a campaign, test every tagged link in the channels where you’ll use it. Paste the URL into a browser, check that the page loads, then inspect the query string in the address bar—look for truncation, encoding errors, or missing parameters.

    Use Google Analytics’ real-time reports or your analytics platform’s debug view to confirm that source, medium, and campaign values appear as expected. If a parameter shows “(not set)” or the visit logs as direct, the tag broke somewhere between generation and click.

    For high-volume campaigns, script a validator: fetch each link, parse the query string, and flag any value longer than 100 characters or any unencoded special character. A ten-minute script run before launch catches most breaks before they cost you data.

    If you manage UTM tagging across a team, document a naming convention—lowercase, hyphens instead of spaces, no special characters—and enforce it with a shared spreadsheet or tagging tool. Consistency prevents collisions and makes historical comparison possible.

    UTM parameters are simple until scale, encoding, and platform quirks collide. Test every link, encode special characters, and keep campaign names short enough to survive the 2,000-character browser floor. The five minutes you spend validating a URL saves the hours you’d lose reconciling attribution gaps later.

    Want step-by-step guides on analytics, traffic, and tool mechanics? Subscribe to One Two Three Send—one focused article every day, no fluff.

  • Analytics export schedules: daily, weekly, and when data vanishes

    Analytics export schedules: daily, weekly, and when data vanishes

    Analytics export schedules: daily, weekly, and when data vanishes
    Photo: Saleemkce via Wikimedia Commons (CC BY-SA 4.0)

    If you run an online business on scheduled analytics exports—weekly traffic reports, monthly revenue snapshots, subscriber growth CSVs—you’ve probably assumed those files live forever. They don’t. Most platforms auto-delete exports after a retention window, and that window varies wildly by tool.

    Miss the download window, and you lose historical granularity. Wait too long to pull a quarterly comparison, and the raw data is gone. Here’s how export schedules actually work, where data disappears, and how to keep what matters.

    Retention windows by platform type

    Google Analytics 4 stores raw event data for 2 or 14 months depending on your retention setting (checked November 2026). Once that window closes, aggregated reports persist, but user-level and event-level exports disappear. If you export a custom exploration today and try to re-run it 15 months later with 14-month retention, the underlying data won’t exist.

    Plausible Analytics keeps all dashboard data indefinitely, but CSV exports depend on your plan. The Growth and Business tiers (checked November 2026) allow unlimited historical exports; the free tier does not guarantee export retention beyond the visible dashboard range.

    For email platforms, MailerLite retains campaign reports indefinitely but limits bulk subscriber export history. ConvertKit keeps subscriber activity logs, but automated export URLs generated via Zapier or Make expire after 30 days unless you store the file externally.

    Payment processors differ too. Stripe keeps transaction data indefinitely in the dashboard, and API access stretches back to account creation, but scheduled payout reports in the Dashboard only go back 12 months (checked November 2026) unless you use the Sigma reporting add-on.

    Scheduled exports vs. on-demand pulls

    Scheduled exports—daily summary emails, weekly Slack digests, monthly CSV drops—usually generate a file once and store it temporarily. If the platform emails you a link, that link often expires. Google Analytics 4 scheduled email reports don’t include raw data; they’re summary PDFs. To get the CSV, you need to run the exploration manually or use the API.

    On-demand exports give you control but require discipline. If you wait until the end of a quarter to pull subscriber growth data and your platform only retains 90 days of granular activity, you’ll get aggregated counts but lose the daily breakdown you need for trend analysis.

    For operators running content businesses, this gap shows up when you try to correlate a traffic spike with a specific campaign six months later. The campaign report exists, but the session-level data—landing page, referrer, time on page—has expired.

    What to export and when

    Pull event-level or user-level data monthly if your platform has a retention limit. For Google Analytics 4, export custom explorations with user or event scope at least once per retention period. Store these as dated CSVs in a dedicated folder—cloud storage works, but name the files with ISO dates (2026-11-01) so they sort chronologically.

    For email platforms, export your full subscriber list with custom field data and engagement scores monthly. Even if the platform keeps the list live, historical snapshots let you reconstruct churn cohorts and identify when engagement patterns shifted.

    Revenue data from Stripe, PayPal, or Gumroad should be pulled quarterly at minimum. Use the platform’s native export or API to grab line-item transaction detail, not just summary totals. If you’re using Stripe, the Reporting API (checked November 2026) gives you access to all transactions, but you need to query it—scheduled reports don’t include everything.

    Where automated exports fail

    Zapier and Make can schedule exports, but both have storage limits. Zapier’s task history keeps run logs for 30 days on paid plans (checked November 2026), and attached files disappear with the logs. If your Zap emails you a weekly GA4 export and you delete the email, the data is gone.

    Make stores execution history for 30 days on the free tier, longer on paid plans, but file attachments are not archived indefinitely. Route exports to Google Drive, Dropbox, or an S3 bucket instead of relying on the automation platform’s storage.

    Email-based exports—platforms that send you a CSV link via email—expire fast. Most links are pre-signed URLs with 7- to 14-day lifespans. Download immediately or set up a filter that auto-saves attachments to cloud storage.

    For operators managing multiple income streams or traffic sources, centralising exports matters. A single missed monthly pull can break year-over-year comparisons. Set calendar reminders, or build a monthly export checklist that covers analytics, email, payments, and any API-fed dashboards.

    Want more infrastructure breakdowns like this? Subscribe to One Two Three Send for weekly deep-dives into the tools and workflows that keep online businesses running.