Author: onetwothreeadmin

  • Social media schedulers don’t understand momentum

    Social media schedulers don’t understand momentum

    Every social media scheduling tool sells the same dream: batch your content on Sunday, set it, forget it, and watch the engagement roll in. The reality is messier. Most schedulers are built for your convenience, not for the way social platforms actually distribute content.

    The gap between those two things costs you reach, replies, and revenue. Here’s why—and what operators who treat social as a revenue channel do differently.

    Algorithms reward immediate engagement, not post volume

    Instagram, LinkedIn, X, and Threads all prioritise posts that generate fast engagement in the first 30–90 minutes. A post that gets five likes in three minutes will be shown to more people than a post that gets fifty likes over six hours.

    Most scheduling tools drop your post at the appointed time and walk away. They don’t tell you it went live. They don’t surface replies. They don’t nudge you to engage with early comments. So your post sits there, algorithmically invisible, while you’re in a meeting or asleep.

    This is the momentum problem: the content goes out, but you’re not there to amplify it when it matters most.

    What “being there” actually looks like

    The operators I know who get consistent reach from social do three things most schedulers can’t automate:

    • They reply to comments in the first hour. Not just “thanks”—they ask follow-up questions, tag other accounts, extend the thread. Platforms interpret this as a signal that the post is worth showing to more people.
    • They repost or quote-tweet their own content 90 minutes later if it’s gaining traction. This isn’t spam; it’s recognising when something is working and giving it a second push while the algorithm window is still open.
    • They kill underperforming posts early. If a LinkedIn post has three likes after two hours, they delete it and try a different angle the next day. No point leaving low-engagement content on your profile where it trains the algorithm to show you to fewer people next time.

    None of this is possible if you’re batching twelve posts on a Sunday and forgetting about them until Friday.

    Tools that get closer to solving this

    A handful of schedulers have started building features that acknowledge the momentum problem, though none solve it completely.

    Publer sends you a mobile notification the moment your post goes live, and you can reply to comments directly in the app without opening six different social platforms. It’s not perfect—engagement still lags compared to posting natively—but it’s faster than logging into Buffer, realising a post went out two hours ago, and scrambling to reply.

    Typefully lets you queue “chain” posts on X, where the second tweet in a thread only goes out if the first one hits a certain engagement threshold. It’s a crude version of momentum-aware scheduling, but it’s something.

    Meta Business Suite (for Instagram and Facebook) has a “boost post” button that appears when a post is outperforming your average. You can turn $20 into 5,000 extra impressions in the same 90-minute window that matters algorithmically. Most third-party schedulers don’t surface this option at all.

    The manual workflow that still beats automation

    Here’s what works for solo operators who don’t have a social media manager: schedule the post, but block 15 minutes on your calendar starting five minutes after it goes live.

    In those 15 minutes:

    • Reply to every comment, even if it’s just a sentence.
    • Share the post to your Instagram story or LinkedIn with a one-sentence callout.
    • DM it to two or three people you know will engage.

    This isn’t scalable if you’re posting ten times a day. But if you’re posting once a day on two platforms—which is what most indie operators actually do—it’s 30 minutes of work that doubles your reach.

    The scheduler gets the post out on time. You handle the momentum. That division of labor is honest about what software can and can’t do.

    What this means for your workflow

    If social is a meaningful traffic or revenue channel for you, treat the first 90 minutes after a post goes live as sacred. Don’t batch-and-forget. Don’t let the post sit while you’re in another tab.

    If you can’t be there in the first 90 minutes, don’t schedule the post for that time. Move it to a slot where you’ll actually be available. A post that goes out at 11 a.m. with you present will outperform a post that goes out at the “optimal” 9 a.m. time with you absent.

    Scheduling tools are useful. But they’re not a substitute for showing up when your content needs you most.

    One Two Three Send covers the tools and workflows that solo operators actually use to run content businesses. Subscribe to get one article like this in your inbox every morning.

    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.

  • ConvertKit’s subscriber tagging limit and how to work around it

    ConvertKit doesn’t advertise it loudly, but there’s a hard limit: 10,000 tags per subscriber. For most operators, that sounds absurdly high. But if you’ve been running automations for a year or more—especially if you tag based on link clicks, form submissions, or purchase behavior—you can hit it faster than you think.

    When you do, ConvertKit silently stops applying new tags to that subscriber. No error message in the UI. No email alert. The automation runs, the subscriber moves through the sequence, but the tag never lands. You only notice when a segment comes up empty or a conditional split sends someone down the wrong path.

    How you hit the limit without realizing it

    The most common culprit: date-stamped tags. If you’re tagging subscribers with things like clicked_link_2024-05-15 or opened_email_january_2026, you’re creating a new tag every single day or week. Multiply that across a dozen automations, and a subscriber who’s been on your list for 18 months can easily accumulate 3,000+ tags.

    Link-click tracking is another one. If you tag every link click with a unique identifier—say, clicked_affiliate_link_productA, clicked_affiliate_link_productB, and so on—you’re burning through your tag budget fast, especially if you publish daily or run frequent promotions.

    Purchase tags are safer, but only if you’re disciplined. Tagging purchased_course_A is fine. Tagging purchased_course_A_via_email_campaign_spring2026 is not. The more specific you get, the faster you hit the ceiling.

    How to audit your current tag usage

    ConvertKit doesn’t surface per-subscriber tag counts in the dashboard, so you’ll need to export your subscriber list and count manually. Go to Subscribers → Export, download the CSV, and open it in Google Sheets or Excel. Each subscriber row will have a Tags column with a comma-separated list.

    Use a formula like =LEN(A2)-LEN(SUBSTITUTE(A2,",",""))+1 to count how many tags each subscriber has. Sort descending. If anyone’s above 8,000, you’re close to the edge.

    While you’re in there, scan for patterns. Look for date-stamped tags, redundant event tags, or anything that increments indefinitely. Those are your cleanup targets.

    Two strategies to stay under the limit

    Strategy one: replace incremental tags with custom fields. Instead of tagging last_clicked_2026-05-24, create a custom field called last_click_date and update it with each action. Custom fields don’t count toward the tag limit, and you can still segment or filter by date. The tradeoff: you lose the historical record. If you need to know every date someone clicked, this won’t work. But if you only care about the most recent action, it’s cleaner.

    Strategy two: archive old tags in bulk. ConvertKit lets you remove tags from subscribers, but there’s no native “delete all tags older than X date” feature. You’ll need to export, filter by tag name pattern (e.g., anything containing 2024), then use the bulk actions menu to remove those tags from the affected subscribers. This is manual, but if you do it quarterly, it keeps your tag count manageable.

    One more option: if you’re tagging for analytics purposes—tracking which emails drove the most clicks, for example—consider moving that data out of ConvertKit entirely. Tools like Plausible or Fathom can track link clicks via UTM parameters, and you won’t burn tags on behavior you’re only measuring, not acting on.

    When the limit actually matters

    For most solo operators, 10,000 tags per subscriber is still overkill. If you’re running a simple welcome sequence, a few product-based segments, and occasional broadcasts, you’ll never get close. The limit only becomes a problem if you’re running complex, multi-branch automations that tag aggressively at every decision point.

    But if you are in that category—if you’re running a membership site, a course platform, or a content business with dozens of lead magnets and automations—this is worth auditing now, before a subscriber silently stops receiving the tags that trigger your most important sequences.

    Want more feature breakdowns like this? Subscribe to One Two Three Send for weekly deep dives on the tools that run your online business—no fluff, just the mechanics that matter.

  • Zapier’s Digest feature: batch updates without spamming your inbox

    Zapier’s Digest feature: batch updates without spamming your inbox

    Most automation workflows fire once per trigger. Someone fills out a form, Zapier fires. A new row hits your sheet, Zapier fires again. That’s fine when you get three events a day. It’s a disaster when you get thirty.

    Zapier’s Digest step exists to solve that problem. Instead of sending you a Slack notification for every new subscriber or a separate email for every form submission, Digest collects those events over a set time window—hourly, daily, or weekly—and bundles them into a single payload.

    It’s one of Zapier’s least-documented features, and most operators don’t know when to use it or how to configure it properly. Here’s what it does, when it works, and one setup mistake that breaks the entire workflow.

    How Digest actually works

    Digest sits between your trigger and your action. Every time the trigger fires, Zapier adds that event to a temporary storage queue instead of immediately passing it downstream. When your chosen time window closes—say, every day at 9 a.m.—Zapier releases the entire batch as a single step output.

    You configure three things: the digest key, the time interval, and the data format. The digest key groups events together; if you’re batching form submissions by type, you’d use a key like form_name. The time interval sets when the batch releases: every hour, every day at a specific time, or every week on a chosen day. The data format determines whether Zapier sends a line-item list or a concatenated text block.

    Common use cases: daily summary emails of new subscribers, weekly Slack digests of GitHub issues, hourly rollups of customer support tickets. Anywhere you’d rather see ten items at once than ten separate notifications.

    When batching saves time, and when it hides problems

    Digest works best when the underlying event is informational rather than urgent. If you’re tracking new blog comments or monitoring social mentions, a daily rollup keeps your inbox clean without missing anything critical.

    It breaks down when the event requires immediate action. If you’re using Digest to batch payment failures or security alerts, you’ve just introduced a delay that could cost you money or trust. A payment fails at 10 a.m., but you don’t see it until the 5 p.m. digest fires—by then, the customer has already churned or disputed the charge.

    The other failure mode: data overload. If your digest regularly contains 50+ items, you’re not reading it—you’re archiving it. At that point, Digest isn’t solving a notification problem; it’s hiding a workflow problem. You probably need filtering, segmentation, or a different tool altogether.

    The setup mistake that silently breaks Digest

    Here’s the trap: Digest only works if your Zap actually runs during the release window. If your trigger hasn’t fired in the past 24 hours and you’ve set a daily digest, Zapier won’t release the batch—it needs at least one new event to trip the release logic.

    That means if you’re batching low-frequency events—say, a weekly digest of new affiliate signups—you could end up with no output at all if no one signed up that week. Zapier won’t send an empty digest; it just skips the release entirely.

    The workaround: pair Digest with Zapier’s Schedule trigger instead of relying on the original event trigger. Set a daily or weekly schedule, then pull the digest data manually via a Formatter step or a webhook. This guarantees the release window fires even when the source data is quiet.

    One non-obvious configuration tip

    Most operators set their digest interval to align with their own schedule—daily at 9 a.m., for example. That’s fine for personal workflows, but if you’re sending digests to a team or a client, you want the release time to match their context, not yours.

    If you’re summarising support tickets for a remote team across three time zones, a single 9 a.m. UTC digest lands at 4 a.m. for some people and lunchtime for others. Instead, duplicate the Zap and configure separate digests for each region, or use Zapier’s Paths feature to route events into time-zone-specific buckets before they hit Digest.

    And if you’re batching user-facing data—like a weekly email summarising content performance for your readers—test the digest output format carefully. Zapier’s default line-item formatting often includes raw field names and extra punctuation that looks fine in Slack but breaks in an HTML email template. You’ll need a Formatter step after Digest to clean it up.

    When to skip Digest entirely

    Two situations where Digest isn’t the right tool: when you need conditional logic per event, and when your downstream action can already handle bulk data.

    If you’re filtering events based on custom field values—say, only sending a notification when a form submission includes a specific keyword—you need to apply that filter before Digest, not after. Otherwise, you’re batching everything and then discarding most of it, which wastes task usage and complicates your Zap history.

    And if your action step already supports bulk operations—like updating multiple rows in a Google Sheet or sending a batch email via an API—you don’t need Digest at all. Use Zapier’s native Looping or Line Item handling instead, which gives you more control over error handling and retry logic.

    Digest is useful, but it’s not universal. The best automation workflows batch strategically, not reflexively.

    Want more breakdowns like this? Reply and tell me which Zapier step or automation pattern you want explained next—I’ll cover it in a future issue.

  • Beehiiv’s paid subscriptions: setup, fees, and the VAT surprise

    Beehiiv’s paid subscriptions: setup, fees, and the VAT surprise

    Beehiiv launched native paid subscriptions in 2023, positioning itself as the all-in-one platform that doesn’t need Stripe integration or third-party membership plugins. For operators already using Beehiiv for free newsletters, flipping the paid switch looks frictionless. But the setup hides complexity that surfaces once you start collecting money across borders.

    Here’s what actually happens when you turn on paid subscriptions, what it costs, and the tax issue that catches most operators off guard.

    How Beehiiv paid subscriptions work

    Beehiiv handles payment processing, subscriber management, and content gating in one interface. You set your price—monthly, annual, or both—and designate which posts are free versus paid. Beehiiv uses Stripe under the hood but abstracts the integration: you connect your Stripe account once during setup, and Beehiiv manages checkout, invoicing, and failed payment recovery.

    The platform supports tiered pricing, free trials, and discount codes. You can also gate individual posts retroactively, which is useful if you’re testing paid content before fully committing to a subscription model.

    One non-obvious benefit: Beehiiv’s referral program integrates with paid tiers. If a free subscriber refers enough readers, they can unlock paid content without paying. This works well for growth-focused operators who want to reward evangelists, but it complicates revenue forecasting—your paid subscriber count and MRR won’t always move in lockstep.

    The fee structure

    Beehiiv takes a 2.9% platform fee on top of Stripe’s standard processing fees (2.9% + $0.30 per transaction in the U.S.). That means you’re paying roughly 5.8% + $0.30 per transaction when someone subscribes.

    For a $10/month subscription, you net around $9.12 after fees. At $100/month, you keep $94.12. The percentage hit is consistent, but the flat $0.30 fee stings more on lower-price subscriptions.

    Beehiiv’s fee applies to your plan tier, not your revenue size. Whether you’re on the Scale plan ($99/month) or Launch (free), the 2.9% fee remains. This is different from platforms like Substack, which take 10% but don’t charge a base platform fee.

    If you process $5,000/month in subscriptions, Beehiiv’s cut is $145. Substack’s would be $500. The breakeven point sits around $3,500/month in subscription revenue—below that, Beehiiv’s model costs less; above it, the flat percentage wins.

    The VAT problem nobody mentions upfront

    Beehiiv does not automatically handle VAT, GST, or sales tax collection for non-U.S. subscribers. If you have paying subscribers in the EU, UK, Australia, or other VAT-registered regions, you are responsible for compliance.

    Stripe can calculate and remit taxes if you enable Stripe Tax, but Beehiiv’s integration doesn’t surface this option in the dashboard. You have to configure it directly in your Stripe account, then ensure Beehiiv passes the correct billing address data to Stripe during checkout.

    Most operators discover this after their first invoice from a European subscriber. If you’re not charging VAT and you cross registration thresholds (€10,000 in EU sales), you’re technically operating outside compliance. Fixing it retroactively means either absorbing the tax yourself or awkwardly re-invoicing subscribers.

    If you’re U.S.-based and expect most subscribers to be domestic, this may not matter in year one. But if you’re writing for a global audience, budget time to either enable Stripe Tax or work with an accountant who understands digital service VAT rules.

    When to use Beehiiv paid vs. an external membership tool

    Beehiiv’s native subscriptions work best when:

    • Your entire business is the newsletter—no courses, downloads, or community access
    • You want one dashboard for content, audience, and revenue
    • You’re okay with Beehiiv owning the checkout experience and subscriber relationship

    Skip Beehiiv paid and use a dedicated membership platform (Memberful, Ghost, or a WordPress membership plugin) if:

    • You need complex access rules—time-limited content, drip courses, or tiered community access
    • You want full control over tax settings, invoicing, and subscriber data portability
    • You plan to sell more than just newsletter access (e.g., templates, coaching, or archived resources)

    Beehiiv’s model is fast to launch but rigid once you outgrow simple “free vs. paid” segmentation. Migrating paying subscribers off the platform later is possible, but it requires CSV exports, manual Stripe imports, and subscriber communication to avoid confusion or churn.

    If you’re testing paid for the first time and already use Beehiiv, the native option is the fastest validation path. Just know the tax setup isn’t automatic, and the 2.9% fee is a permanent cost unless you move to a different platform.

    Using a different newsletter platform or thinking about switching? Reply and let me know what’s working—or not—in your paid subscription stack. I’ll cover more monetization mechanics in future issues.

    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.

  • Subscription bombing: why bots sign up to your newsletter (and how to block them)

    Subscription bombing: why bots sign up to your newsletter (and how to block them)

    If you run a newsletter, you’ve probably noticed signups appearing in your subscriber list with email addresses that look subtly wrong. Names you don’t recognise. Local-parts with strange dot patterns like [email protected]. All marked as “direct” with no referer, no UTM, no obvious traffic source.

    These aren’t your audience. Your site is being used as a relay in an attack on someone else’s inbox. The technical name is subscription bombing (also called list bombing or mail bombing), and once you know what to look for, you’ll see it on almost every newsletter signup form on the open web.

    What subscription bombing actually is

    An attacker picks a victim — usually one specific email address. They run a bot that visits thousands of unrelated websites that accept newsletter signups and submits the victim’s email to every one of them.

    Within ten minutes, the victim’s inbox fills with two hundred legitimate-looking welcome emails from newsletters they never signed up for. Travel sites, ecommerce stores, hobby blogs, university mailing lists, charity newsletters. Each individual email is innocuous. The pile is the point.

    Your site isn’t being attacked. Your site is being used as a small, expendable cog in an attack on someone you’ve never met.

    Why attackers do this

    The motive is almost always to hide a single critical email from the victim:

    • Credit card fraud cover. The attacker just made a $2,000 purchase on the victim’s stolen card. The bank will send a fraud-alert email within minutes. If that alert is buried under 300 newsletter confirmations, the victim might not see it until after the cancellation window closes.
    • Account recovery. The attacker is trying to take over the victim’s email or banking account. Password-reset confirmations and 2FA codes get buried in the same way.
    • Harassment. Less common, but bombings are sometimes used to make a target’s inbox unusable for days.

    There are services that openly sell this. “1,000-site mail bomb, $30.” They use rented botnets so the requests come from thousands of residential IPs — no single source to block.

    How to spot it on your own list

    Two patterns are diagnostic:

    The dotted-Gmail trick

    Gmail ignores dots in the local-part of an address. [email protected], [email protected], and [email protected] all deliver to the same inbox. Each site’s database stores them as distinct addresses (so per-site dedup doesn’t catch the second signup), but the victim receives every email.

    If you see several Gmail signups in the same short window with unusual dot patterns, those are almost certainly bot signups. Real humans don’t sprinkle random dots through their own email when filling out a form.

    Missing referer, missing UTM, sub-minute conversion

    Bots that target your endpoint directly never load the form page first. They POST straight to the subscribe endpoint with just {email}. As a result:

    • No Referer header.
    • No utm_source on the landing URL.
    • No first-touch attribution cookie.
    • “First seen” and “subscribed” timestamps within seconds of each other.

    A real visitor might land via Facebook, browse for a few minutes, then sign up. Their attribution captures something. Bots leave nothing.

    Layered defences that actually work

    No single check stops subscription bombing. The pattern is layered defences, each catching a slightly different bot class:

    1. Honeypot field. A hidden input field that real humans never see. Bots that scrape the form HTML and fill every input get caught. Cheap, transparent, zero UX impact. Useless against bots that POST straight to the endpoint without loading the form.
    2. Per-IP rate limit. N submissions per IP per hour. Catches bursty single-IP attacks. Useless against distributed botnets across thousands of residential IPs.
    3. MX-record check. Reject signups whose email domain has no MX (mail exchanger) record. Catches typos and made-up domains. Cheap — one DNS lookup. Useless against Gmail-based attacks.
    4. Disposable-domain blocklist. Reject signups from known throwaway services (mailinator, guerrillamail, yopmail, etc.). Useless against real-domain attacks but kills another bot class.
    5. Gmail dot-normalization. Strip dots from the local-part of Gmail addresses before storing. If [email protected] already exists, the second variant gets rejected as a duplicate. Catches dot-trick attacks on a single site (though not across multiple sites).
    6. Cloudflare Turnstile. Invisible CAPTCHA. By far the most effective single layer — it makes bot signups dramatically more expensive to attempt. Some UX cost: real users with strict privacy extensions occasionally fail it.
    7. Double opt-in. Send a confirmation email; only add the subscriber once they click. The standard ESP defence. It doesn’t prevent the bomb (you still send one email) but it stops the victim from being added to your ongoing list, which protects your sender reputation downstream.

    Each layer should silently accept-and-drop suspicious signups — return HTTP 200, never reveal which check tripped. If your endpoint says “rate limited” or “honeypot detected,” attackers immediately adapt.

    What One Two Three Send does out of the box

    As of version 2.0.20, the free plugin’s /wp-json/otts/v1/subscribe endpoint runs four layers automatically:

    • Honeypot on the form (hidden website input — already in earlier versions).
    • Per-IP rate limit — 10 submissions per IP per hour by default, filterable via otts_subscribe_rate_limit_per_hour.
    • MX-record validation on the email domain.
    • Disposable-domain blocklist of ~30 common throwaway services, filterable via otts_subscribe_disposable_domains.

    All four layers silently accept-and-drop — bots can’t fingerprint which check rejected them.

    The Subscribers admin page now has a Delete button on every row for cleaning up signups that slip through. Two new admin-only REST endpoints (DELETE /wp-json/otts/v1/subscriber/{id} and POST /wp-json/otts/v1/subscriber/delete-by-email) let you script bulk cleanups if you need to delete dozens of bot signups at once.

    If your site is being bombed heavily, Cloudflare Turnstile in front of your signup form is the next step. It’s free, integrates in a few lines of JS, and stops the overwhelming majority of attacks that get past the layers above. Double opt-in is the layer after that.

    One thing worth keeping in mind

    If you see fifty bot signups appear in your list, your first reaction will probably be annoyance about list-hygiene. The bigger picture is that fifty real people — strangers, somewhere — just had their inboxes flooded as cover for a fraud or account-recovery attack. Tightening up your form isn’t just protecting your sender reputation. It’s removing one of the small relays that subscription-bombing services rent out by the thousand.

    Every site that adds a honeypot, a rate limit, or a Turnstile widget makes that business model a little less profitable. That’s worth doing.

  • Paid search vs. organic content: which builds revenue faster?

    Paid search vs. organic content: which builds revenue faster?

    Every solo operator hits the same fork in the road: spend money on Google Ads to get traffic today, or invest time in SEO to earn it for free six months from now.

    The conventional advice—”do both”—ignores the reality of limited budgets and single-person operations. You need to pick one, at least to start. Here’s how to make that call based on your business model, your offer, and your tolerance for waiting.

    When paid search wins

    Google Ads gets you in front of buyers the day you launch a campaign. If you’re selling a productised service, a course, or a SaaS tool with a proven conversion rate, paid search lets you test messaging, validate demand, and generate revenue while your content strategy is still a Notion doc.

    The break-even math is simple: if your customer lifetime value is $500 and you can acquire a customer for $150 via Google Ads, you’re profitable from day one. That margin funds more ads, more tests, and eventually the content team you wish you had time to build.

    Paid search also works when your market is narrow and your keywords are cheap. A consultant selling fractional CFO services to SaaS founders can buy “fractional CFO for SaaS” at $8 per click and convert at 5%. That’s $160 per customer—sustainable if the contract is worth $3,000.

    But paid search stops the moment you stop paying. Your cost per acquisition never improves structurally; you’re renting attention, not owning it. And if your offer doesn’t convert above 2%, or your LTV is under $200, the unit economics collapse fast.

    When organic content wins

    SEO is a compounding asset. Publish 50 articles that rank, and they generate traffic—and revenue—for years without additional spend. A tutorial on “how to migrate from Mailchimp to ConvertKit” can drive 400 visits a month for three years, converting 2% of readers into affiliate commissions or newsletter subscribers.

    Organic content works best when you’re building an audience business—newsletters, memberships, affiliate income—or when your product has a long sales cycle. If buyers need to read six articles before they trust you enough to book a call, SEO is feeding that funnel for free while paid ads burn budget on cold traffic.

    The trade-off is time. Expect six months before you see meaningful traffic, and twelve before it becomes a dependable revenue channel. You’re also competing with sites that have been publishing for a decade. Ranking for “email marketing tips” is nearly impossible; ranking for “Beehiiv vs. ConvertKit for paid newsletters” is achievable in 90 days.

    SEO also favours operators who can write. If you’re paying $300 per article to a freelancer, your payback period stretches to 18 months. If you’re writing yourself at 1,000 words per hour, the math tilts in your favour.

    The hybrid play most operators miss

    Here’s the move that works if you have $500/month to spend: run Google Ads on your three highest-intent keywords while you build out the content that will eventually rank for them organically.

    The paid campaign generates revenue and validates which keywords actually convert. The organic content builds slowly in the background. After six months, your articles start ranking, your cost per click drops as organic traffic offsets paid volume, and you can reallocate ad spend to new keywords or turn it off entirely.

    This only works if your paid campaigns are profitable from week one. If you’re losing money on ads while waiting for SEO to kick in, you’re just burning capital in two directions.

    How to choose right now

    If your offer converts above 3%, your LTV exceeds $300, and you need revenue this quarter, start with paid search. Build a single campaign around five keywords, set a $20/day budget, and measure cost per acquisition weekly.

    If you’re pre-revenue, building an audience, or selling something with a six-month consideration cycle, start with organic content. Publish two articles per week for 90 days, target long-tail keywords with under 500 monthly searches, and track rankings in Google Search Console.

    If you’re somewhere in between, run a one-month paid test with a $300 budget. If your CPA is under half your LTV, keep running ads and layer in content. If it’s not, kill the campaign and go all-in on SEO.

    Want more breakdowns like this? Subscribe to One Two Three Send for weekly tactics on traffic, tools, and revenue—written for operators who don’t have a marketing team.

    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.

  • WordPress cron jobs: what runs when and how to fix the slowdowns

    WordPress cron jobs: what runs when and how to fix the slowdowns

    WordPress cron is a lie. It’s not a scheduled task runner—it’s a script that fires when someone visits your site. If nobody visits for an hour, nothing runs for an hour. If fifty people hit your homepage at once, that script might try to run fifty times simultaneously.

    That’s why your admin dashboard sometimes loads slowly, or why your scheduled posts don’t publish at the exact minute you set. Understanding what WordPress cron actually does—and when to replace it—matters once you’re running a content operation that depends on predictable publishing and performance.

    What WordPress cron actually runs

    Every WordPress install has a default set of cron jobs baked in. These include:

    • Checking for plugin and theme updates
    • Publishing scheduled posts
    • Clearing expired transients (temporary data stored in your database)
    • Sending pingbacks and trackbacks
    • Running database cleanup tasks

    Plugins and themes add their own jobs on top of this baseline. Newsletter plugins schedule digest sends. Backup plugins queue nightly snapshots. SEO plugins refresh sitemaps. Social-sharing tools check for new posts to auto-tweet.

    You can see every scheduled task by installing the WP Crontrol plugin. It lists every job, its recurrence interval, and the function it calls. On a typical site with a dozen active plugins, you’ll find twenty to forty jobs running hourly, daily, or weekly.

    Why it slows your site down

    WordPress cron fires on page load. When a visitor requests a page, WordPress checks if any cron jobs are due. If they are, it spawns a background HTTP request back to itself to process them.

    That works fine for low-traffic blogs. But once you’re running a content site with consistent traffic, you hit two problems:

    Multiple simultaneous triggers. If ten people load your homepage within the same second, WordPress might spawn ten parallel cron processes. Those processes compete for database connections and CPU. Your server slows down. Page load times spike.

    Cron jobs that block rendering. Some poorly-coded plugins don’t spawn the background request correctly. Instead, they run their cron tasks inline—before the page finishes loading. A five-second backup task means a five-second delay before your visitor sees anything.

    The standard fix is to disable WordPress cron entirely and replace it with real server-level cron.

    How to replace it with real cron

    Disabling WordPress cron takes one line in your wp-config.php file:

    define('DISABLE_WP_CRON', true);

    Add that above the line that says “That’s all, stop editing!” and save the file. WordPress will stop checking for due tasks on every page load.

    Now you need to tell your server to run those tasks instead. Most shared hosts and managed WordPress hosts (including BigScoots) let you add cron jobs through cPanel or a similar control panel.

    Create a new cron job that runs every five or ten minutes, pointing to:

    wget -q -O - https://yourdomain.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1

    Or, if your host supports it:

    php /path/to/your/wordpress/wp-cron.php

    The first version uses HTTP to trigger the cron script, just like WordPress does—but on a predictable schedule instead of on every page load. The second version runs it directly via PHP, which is faster and doesn’t consume an HTTP request slot.

    Check your host’s documentation or ask support which syntax to use. Most managed WordPress hosts already handle this for you if you disable WP_CRON in config.

    When to leave WordPress cron enabled

    If your site gets fewer than a hundred visits per day, the default behavior is fine. The overhead is negligible, and you avoid the hassle of configuring server-level cron access.

    If you’re on a staging site or local development environment, leave it on. You need to visit the site to trigger tasks anyway, and setting up real cron for ephemeral environments isn’t worth it.

    But if you’re publishing on a schedule, running automated workflows, or seeing unexplained slowdowns during traffic spikes, disable WP_CRON and hand the job to your server. You’ll get predictable task execution and faster page loads.

    One non-obvious tip: After you switch to real cron, check WP Crontrol again in a week. Some plugins re-register their tasks incorrectly and create duplicates. If you see the same job listed twice with different intervals, delete the duplicate manually. It won’t break anything—the plugin will recreate the correct version on its next run.

    If this helped, subscribe to One Two Three Send for weekly breakdowns of the tools and infrastructure that actually matter when you’re running a content business solo.

  • Analytics event sampling: why your data vanishes above 500K sessions

    Analytics event sampling: why your data vanishes above 500K sessions

    If you’re running a content site that pulls 500,000+ sessions a month, you’ve probably noticed something strange: your GA4 reports don’t always match. Run the same custom report twice, and the numbers shift. Filter by a specific page or traffic source, and suddenly your totals don’t add up.

    You’re not imagining it. You’ve hit GA4’s sampling threshold.

    Sampling means Google is analysing a subset of your data—not all of it—then extrapolating the results. It’s faster for Google to process, but it quietly erodes the accuracy of every decision you make based on those numbers.

    When sampling kicks in (earlier than you think)

    Google’s documentation says GA4 standard properties support up to 10 million events per month before sampling applies. That sounds like plenty of headroom.

    But sampling doesn’t wait until you hit 10 million events. It starts much earlier—often around 500,000 sessions—when you build custom reports, apply filters, or request data outside the standard date range.

    Standard reports (the pre-built ones GA4 ships with) use aggregated data tables and rarely sample. But the moment you:

    • Add a secondary dimension
    • Apply a segment or filter
    • Build an exploration report
    • Request data older than 14 months

    …GA4 switches to on-the-fly querying, and sampling kicks in if your property is processing enough events.

    You’ll see a green badge in the top-right corner of your report that says “This report is based on X% of sessions.” If that number is below 100%, your data is sampled.

    What gets lost in sampled data

    Sampling doesn’t affect every metric equally. High-level numbers—total sessions, pageviews, users—tend to hold up reasonably well even at 20–30% sampling rates.

    But the more specific your question, the worse sampling performs. If you’re trying to:

    • Identify which blog post drove the most newsletter signups from organic search last quarter
    • Compare conversion rates across traffic sources for a specific product page
    • Measure how a site-speed optimisation affected bounce rates on mobile

    …sampling can distort the answer enough to reverse your conclusions.

    I’ve seen sampled reports show a 15% conversion rate on a landing page when the unsampled data (pulled via BigQuery export) showed 11%. That’s not a rounding error—that’s a different business decision.

    How to reduce or avoid sampling

    If you’re consistently hitting sampling in GA4, you have four options.

    Option one: Narrow your date range. Instead of analysing the last six months, break it into monthly or bi-weekly segments. Smaller queries are less likely to sample. You’ll need to stitch the data together manually, but at least it’s accurate.

    Option two: Use the Data API. GA4’s Reporting API gives you access to unsampled data if your query stays within certain limits. Tools like Google Sheets (via the GA4 add-on) or Looker Studio can pull data this way. It’s slower, and there are still daily quotas, but it bypasses the sampling you see in the GA4 interface.

    Option three: Export to BigQuery. GA4 offers a free BigQuery export (up to 1 million events per day). Once your data is in BigQuery, you can query it without sampling. The trade-off: you need to learn SQL, and you’re managing your own data warehouse. But if you’re making six-figure decisions based on this data, it’s worth it.

    Option four: Upgrade to GA4 360. The enterprise tier starts at $50,000/year (sometimes negotiable to $150,000 depending on scale) and raises sampling thresholds significantly. Unless you’re running a seven-figure media operation, this isn’t realistic.

    When sampled data is good enough

    Not every report needs to be unsampled. If you’re checking whether traffic went up or down this week, or whether your top-performing post is still your top-performing post, a 70% sample is fine.

    But if you’re deciding whether to double down on a traffic source, kill a product, or restructure your content strategy, don’t trust a sampled report. Pull the data via API or BigQuery, or narrow your query until the sampling badge disappears.

    The costliest analytics mistake isn’t picking the wrong tool—it’s trusting incomplete data and not knowing it.

    Using GA4 for attribution or conversion tracking? Subscribe to One Two Three Send and get one operator-focused article like this every day.

  • ChatGPT’s memory feature: what it remembers and when to reset it

    ChatGPT’s memory feature: what it remembers and when to reset it

    ChatGPT’s memory feature lets the model remember details across conversations—your business model, your audience, your tone preferences—so you don’t have to repeat context every time you open a new chat.

    In theory, it’s a time-saver. In practice, it can quietly corrupt every output if you’re not paying attention to what it’s storing.

    Here’s how the feature actually works, what gets saved, and when you should delete everything and start fresh.

    How ChatGPT memory works

    When memory is enabled (it’s on by default for Plus and Team users), ChatGPT stores snippets of information you share across sessions. It doesn’t save full transcripts—it extracts facts, preferences, and instructions it thinks will be useful later.

    For example, if you tell ChatGPT you run a weekly newsletter about WordPress hosting, it might remember that. The next time you ask it to write an email subject line, it’ll assume your audience cares about uptime and page speed without you saying so.

    You can view what’s stored by going to Settings → Personalization → Memory. You’ll see a list of bullet points—some you explicitly told it, others it inferred. You can delete individual memories or wipe everything at once.

    Memory is tied to your account, not a specific conversation. If you start a new chat, the model still has access to everything it saved before.

    When memory improves your workflow

    Memory works best when your business model, audience, and output format are stable. If you’re always writing for the same newsletter, using the same voice, and solving the same kinds of problems, memory removes repetitive context-setting.

    Use cases where it helps:

    • Drafting content: You write every Tuesday for a niche audience. ChatGPT remembers the format, tone, and typical topics without a fresh brief.
    • Generating ideas: You ask for post ideas weekly. It recalls your editorial themes and avoids suggesting topics you’ve already covered.
    • Code or automation help: You’re building Zapier workflows or WordPress plugins. It remembers your stack, your naming conventions, and the APIs you use.

    If you’re working solo and your projects don’t shift much, memory reduces cognitive overhead. You get faster first drafts with less prompting.

    When memory pollutes your output

    Memory becomes a problem when context changes but the model doesn’t know it.

    Say you used ChatGPT to write emails for a SaaS product last month. This month, you’re drafting newsletter content for a coaching business. If memory is still active, it might assume your audience is technical, your goal is conversion, and your tone is formal—none of which apply anymore.

    You won’t always notice. The output will feel slightly off—too corporate, too detailed, too salesy—but you might not trace it back to stale memory.

    Other scenarios where memory breaks down:

    • Client work: You’re writing for multiple clients with different voices. Memory blurs the lines unless you manually reset between projects.
    • Experimentation: You’re testing a new content format or audience. Memory anchors responses to what worked before, even when you’re trying something different.
    • Shared accounts: If you’re on a Team plan and multiple people use the same login, memory mixes everyone’s preferences into a confusing mess.

    The worst part: ChatGPT doesn’t tell you when it’s relying on memory. There’s no citation, no flag. It just quietly applies old context to new requests.

    How to manage memory (and when to delete it)

    Check your memory every few weeks. Go to Settings → Personalization → Memory and scan the list. Delete anything that’s outdated, project-specific, or no longer relevant.

    If you switch projects or clients frequently, disable memory entirely. You’ll lose the convenience, but you’ll avoid contaminated outputs. You can toggle it off in the same settings menu.

    If you want memory for some tasks but not others, use Temporary Chat mode (the icon in the sidebar). Conversations in that mode don’t update memory and don’t reference what’s stored. It’s useful for one-off requests or experimenting with a new voice.

    One non-obvious tip: when you do want ChatGPT to remember something, tell it explicitly. Don’t assume it’ll pick up on subtle hints. Say, “Remember: my newsletter audience is non-technical founders, and I always write in second person.” That instruction will stick better than hoping the model infers it from a single example.

    Want more breakdowns like this? Subscribe to One Two Three Send and get one operator-focused article every day—no fluff, no listicles, just tools and tactics that work.

  • Affiliate link cloaking: compliance, tracking, and when to skip it

    Affiliate link cloaking: compliance, tracking, and when to skip it

    Affiliate link cloaking—redirecting yoursite.com/go/product to partnersite.com/?ref=yourID—sounds like good housekeeping. Cleaner URLs, consistent branding, easier tracking. But it introduces technical risk, compliance obligations, and platform dependency that many operators don’t plan for.

    Here’s what actually changes when you cloak links, and when you’re better off leaving them naked.

    What cloaking does (and doesn’t) solve

    Link cloaking replaces long, ugly affiliate URLs with short, branded redirects. Instead of sharing https://convertkit.com?lmref=abc123xyz, you serve yoursite.com/convertkit and 301-redirect behind the scenes.

    The benefit is consistency. Readers see your domain. You can swap the destination URL without editing published content. You centralize click tracking in one place—your own server logs or a plugin like Pretty Links or ThirstyAffiliates.

    What it doesn’t do: improve deliverability, hide the affiliate relationship from networks, or make the link more trustworthy. Email clients still see the final destination after following the redirect. Affiliate networks log the same click. Readers who hover still see the redirect if they check the status bar.

    And you’ve added a round-trip dependency: your server must respond before the affiliate network sees the click. If your host is slow, you’ve introduced latency. If your site goes down, the link breaks entirely.

    FTC disclosure and platform terms

    Cloaking doesn’t exempt you from disclosure rules. The FTC’s Endorsement Guides require clear, conspicuous notice when you earn from a recommendation. A short slug like /go/ or /recommends/ signals commercial intent, but it’s not a substitute for plain-language disclosure near the link.

    Some affiliate programs explicitly prohibit cloaking. Amazon Associates’ Operating Agreement bans link shortening or masking that obscures the final destination. Commission Junction and ShareASale allow it, but require that the redirect preserves tracking parameters and doesn’t mislead users.

    Check your agreement before you automate. Violating terms can mean forfeited commissions or account closure, and most networks won’t warn you—they’ll just stop paying.

    When cloaking makes sense

    If you publish across multiple platforms—blog, newsletter, podcast show notes—and want consistent analytics, cloaking centralizes your data. You can see aggregate clicks in one dashboard instead of stitching together reports from five affiliate portals.

    If you rotate offers or test different partners, cloaking lets you update the destination without republishing old content. A post from 2023 can point to a new tool in 2026 if the /email-tool slug stays the same.

    If you’re building a resource hub or comparison page, branded slugs make the link structure easier to maintain. /bluehost, /siteground, and /bigscoots are more memorable than tracking IDs.

    When to leave links uncloaked

    In email, cloaking adds a redirect that some inbox providers flag. Mailchimp, ConvertKit, and MailerLite preserve click tracking without requiring your own redirect layer. Adding a second hop can increase latency or trigger spam filters if your domain reputation is newer than the affiliate network’s.

    If you’re solo and publishing sporadically, the maintenance overhead isn’t worth it. Cloaking plugins need updates. Redirects need testing. If a slug breaks and you don’t notice for two months, you’ve lost clicks and trust.

    If the affiliate program forbids it, don’t bother trying to hide the relationship. Amazon’s SiteStripe links work fine as-is. Trying to mask them risks more than you gain.

    And if you’re linking to a brand readers already recognize—Stripe, Shopify, Adobe—there’s no branding advantage. stripe.com is more trustworthy than yoursite.com/stripe to someone who’s never heard of you.

    Implementation trade-offs

    WordPress plugins like Pretty Links and ThirstyAffiliates handle the redirect and log clicks in your database. Easy to set up, but you’re querying your own database on every click. High-traffic affiliates can strain shared hosting if you’re not caching redirects.

    Link management tools like Rebrandly or Short.io offload the redirect to their infrastructure. Faster, more reliable, but you’re paying monthly and trusting a third party with your click data. If they change pricing or shut down, you’re migrating hundreds of links.

    Server-level redirects—defined in .htaccess or Nginx config—are fastest and least fragile, but require manual editing every time you add a link. Fine if you have six evergreen affiliate relationships. Unworkable if you’re testing new offers weekly.

    Pick the method that matches your volume and technical comfort. If you’re managing fewer than 20 affiliate links, a plugin is fine. If you’re running a deals site with 200+ partners, invest in dedicated infrastructure or a SaaS redirect service.

    Got a question about affiliate operations, tracking, or compliance? Reply to this email—operator stories make the best future articles.