Author: onetwothreeadmin

  • WordPress database backups fail silently—here’s what to check

    Most solo operators discover their WordPress backup plugin failed the moment they need to restore something. By then, weeks or months of content, subscriber data, or order history are gone.

    Silent backup failures happen more often than platform dashboards admit. Plugins report green checkmarks while actual backups sit incomplete, corrupt, or missing entirely. This guide walks through the specific checks that catch failures before they cost you.

    Why WordPress backups fail without throwing errors

    Backup plugins rely on server resources—CPU, memory, execution time—that shared hosting environments throttle aggressively. When a backup job hits a limit, the process dies mid-export. The plugin logs a start time, assumes success, and moves on.

    Three common culprits:

    • PHP max_execution_time caps kill long-running database exports, especially on sites above 500 MB. The plugin times out before writing the full SQL dump.
    • Remote storage API failures break silently when Google Drive, Dropbox, or S3 tokens expire or hit rate limits. The plugin creates a local file but never uploads it.
    • Database table corruption during export causes incomplete dumps. The plugin writes a file, but restoring it fails because critical tables are missing rows.

    Most backup dashboards show “last backup: 2 hours ago” without validating file integrity or confirming the remote copy exists.

    Manual checks that catch silent failures

    Run these four checks monthly, or after any plugin/theme update that changes your database schema.

    1. Verify remote storage actually received the file. Log into your Dropbox, Google Drive, or S3 bucket. Sort by date modified. Confirm the most recent .zip or .sql file timestamp matches your plugin’s “last backup” log. File size should match or exceed previous backups unless you deleted content.

    2. Download and unzip the backup locally. Corrupt archives throw errors when you try to extract them. If the .zip opens but the database .sql file inside is under 1 MB on a site with years of posts, the export likely truncated.

    3. Scan the SQL dump for table completeness. Open the .sql file in a text editor. Search for CREATE TABLE statements. You should see wp_posts, wp_postmeta, wp_users, wp_options, and any custom tables your plugins add. Missing tables mean the backup won’t restore your site to its current state.

    4. Check plugin error logs, not dashboards. Most backup plugins write verbose logs to /wp-content/uploads/backups/ or similar. Look for lines containing “timeout,” “memory,” “curl error,” or “failed to write.” These warnings rarely surface in the admin UI.

    Fixing the three most common failure modes

    Execution timeouts: Increase max_execution_time in your php.ini or .htaccess, or split backups into separate database and file jobs. Plugins like UpdraftPlus let you run database and media exports independently, each staying under time limits.

    Remote storage auth failures: Reauthorize API connections every 90 days. Google Drive tokens expire; Dropbox app permissions get revoked during security audits. Test remote upload manually after reauthorizing.

    Database corruption: Run wp db repair via WP-CLI, or use phpMyAdmin’s repair function on tables flagged in error logs. Schedule this quarterly if you run high-traffic membership or e-commerce sites that hammer the database.

    When to test a full restore

    Backups you’ve never restored are backups you don’t actually have. Spin up a local environment or staging server once per quarter and restore your most recent backup end-to-end. Time the process. Note what breaks.

    Common restore gotchas: hardcoded domain URLs in serialized post meta, missing .htaccess rules, and plugins that store config outside the database (API keys in wp-config.php). Document the manual steps required so you’re not figuring them out during an outage.

    If restoring takes longer than 30 minutes or requires more than three manual fixes, your backup strategy isn’t production-ready. Simplify your plugin stack or move to managed WordPress hosting that handles backups at the server level.

    Set a calendar reminder right now: first Sunday of every month, download your latest backup and verify the SQL file opens and lists your tables. It takes four minutes and catches 90% of silent failures before they matter.

    What’s your backup horror story? Hit reply—we’re collecting operator war stories for a future piece on disaster recovery workflows that actually work under pressure.

  • Monetisation attribution dies in multi-touch funnels

    Monetisation attribution dies in multi-touch funnels

    You run a sponsored issue, push an affiliate link on social, mention a product in your archive, and three weeks later someone buys. Your analytics platform credits the sale to “direct traffic” or the last click before checkout. You have no idea which channel actually worked.

    This isn’t a tracking-pixel problem. It’s a structural flaw in how most solo operators measure revenue when the buyer journey spans email, social, organic search, and word-of-mouth over days or weeks.

    Single-touch attribution—first click or last click—works when the path is short. It collapses when your funnel has five steps, three platforms, and a fourteen-day consideration window. And if you’re running a content business, that’s the norm, not the exception.

    Why last-click attribution lies

    Most analytics tools default to last-click: the final referrer before conversion gets full credit. If someone clicks your affiliate link in a newsletter, browses for ten minutes, leaves, then Googles the product name two days later and buys via organic search, Google gets the sale. Your newsletter sees nothing.

    Stripe’s payment links don’t carry session history. Gumroad’s dashboard shows referrer data, but only for the session that completed checkout. ConvertKit and Beehiiv track link clicks, but those events live in separate databases from your revenue analytics. Unless you stitch them manually, the attribution breaks at the platform boundary.

    First-click attribution has the opposite problem: it over-credits discovery and ignores the nurture work. If someone found you via a Reddit comment six months ago, subscribed, read forty emails, then bought after a single product mention, Reddit gets full credit. The forty emails that built trust? Invisible.

    Multi-touch models operators actually use

    Enterprise marketing teams run algorithmic attribution—machine learning models that weight every touchpoint. Solo operators don’t have the data volume or engineering budget for that. But three simpler models work without custom code:

    Linear attribution: Split credit equally across all known touchpoints. If someone clicked three emails, visited your site twice via organic search, and converted via a social link, each touchpoint gets 20%. This assumes every step mattered equally, which is wrong, but it’s better than crediting one channel with 100%.

    Time-decay attribution: Give more weight to recent interactions. Touchpoints closer to conversion get higher percentages. A click seven days before purchase counts less than a click seven hours before. This mirrors how buying intent escalates, but it still undervalues early discovery.

    Position-based (U-shaped) attribution: Credit 40% to first touch, 40% to last touch, and split the remaining 20% across middle interactions. This rewards both discovery and conversion while acknowledging the nurture steps. It’s the model I see most operators settle on after trying the others.

    How to track multi-touch revenue without enterprise tools

    You don’t need Segment or a six-figure contract with HubSpot. You need three things: consistent UTM tagging, a spreadsheet or lightweight database, and a workflow that logs touchpoints before checkout.

    Tag every outbound link with UTM parameters that include source, medium, and campaign. Your newsletter links get ?utm_source=newsletter&utm_medium=email&utm_campaign=2026-06-06. Social posts get ?utm_source=twitter&utm_medium=social. Affiliate mentions get a unique campaign slug. Apply this everywhere, every time.

    Use a tool that logs those UTM parameters at the session level. Google Analytics 4 can do this if you set up custom dimensions for first and last UTM source. Plausible Analytics stores referrer data in its event stream. Fathom Analytics offers custom event properties. All three let you export CSVs with timestamp, session ID, and UTM values.

    At checkout, append a hidden field or order note that captures the customer’s email or a hashed session ID. In Stripe, use metadata fields. In Gumroad, add a custom field to the checkout form. In WooCommerce, log UTM data to the order meta table with a lightweight plugin or custom function.

    Once a week, export your revenue data and your session logs. Match customer email or session ID across both. Map out the sequence of touchpoints that led to each purchase. Assign attribution percentages using whichever model you chose. Update a running tally of channel performance.

    This workflow takes about ninety minutes a week for a business doing twenty to fifty transactions a month. It’s manual, but it’s accurate enough to shift budget and effort toward the channels that actually drive revenue.

    What breaks and when to simplify

    Multi-device journeys wreck this system. If someone reads your newsletter on mobile, researches on desktop, and buys on tablet, session IDs won’t match unless they log in. Email hashing helps, but only if you collect it at multiple touchpoints.

    Word-of-mouth and dark social—shares via Slack, WhatsApp, direct messages—show up as direct traffic. You can’t track them without unique links for every share, which isn’t realistic. Accept that 20–30% of your revenue will stay unattributed.

    If your average sale is under $30 and you’re doing fewer than ten transactions a week, the juice isn’t worth the squeeze. Stick with last-click and focus on growing volume instead of optimising attribution. Multi-touch matters when you’re allocating real money across channels or deciding which content to double down on.

    Want more breakdowns of what works and what breaks in online-business operations? Subscribe to One Two Three Send and get one focused article like this in your inbox every week.

    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 CDN purge failures cost you traffic—here’s why

    WordPress CDN purge failures cost you traffic—here’s why

    You publish a time-sensitive post, hit save, and assume it’s live everywhere. But CDN cache purge doesn’t always work the way you think—and when it fails silently, you’re serving stale content to the readers who matter most.

    This isn’t a theoretical edge case. CDN purge failures happen daily across WordPress sites, especially when you’re running caching layers, security plugins, or multi-region delivery. The result: your homepage shows yesterday’s headline, your pricing page displays the old offer, and Google crawls a version of your post that’s missing the updated title tag.

    Here’s what actually happens when you hit publish, why purge requests fail, and how to verify your content is live before you share it.

    What happens when you publish a WordPress post

    When you click “Publish” in WordPress, several cache layers need to clear:

    • Object cache (Redis or Memcached, if enabled)
    • Page cache (WP Rocket, W3 Total Cache, LiteSpeed Cache)
    • CDN edge cache (Cloudflare, Bunny CDN, StackPath)
    • Browser cache (controlled by headers, not purge requests)

    Your caching plugin is supposed to send a purge request to the CDN when content changes. But purge requests are API calls—and API calls fail. The CDN might time out, the plugin might send the wrong URL format, or your firewall might block the purge webhook.

    The worst part: most purge failures are silent. WordPress doesn’t throw an error. The CDN logs the request but doesn’t retry. You think the post is live, but edge servers in London, Sydney, and Singapore are still serving the cached version for another hour.

    Why CDN purge requests fail

    URL mismatch between WordPress and the CDN. If your WordPress site uses http:// internally but your CDN serves https://, the purge request targets the wrong URL. Same problem if you’re using www. in one place and not the other. The CDN gets a purge request for a URL it doesn’t recognize, shrugs, and moves on.

    Wildcard purge disabled or misconfigured. Some CDN plans—especially free tiers—limit wildcard purges. If you update a post that appears on your homepage, archive pages, and RSS feed, you need to purge all of those URLs. If your plugin tries to purge /blog/* but your CDN only allows exact-match purges, nothing clears.

    Rate limiting on the CDN API. Cloudflare’s free plan allows 1,200 purge requests per day. That sounds like a lot until you’re editing a post multiple times, auto-saving drafts, and triggering purge requests on every revision. Hit the limit, and your next purge fails silently.

    Caching plugins that don’t talk to your CDN. Not every WordPress cache plugin supports every CDN. WP Rocket has built-in Cloudflare integration. LiteSpeed Cache works natively with LiteSpeed servers. But if you’re using a generic cache plugin with a smaller CDN, you might need a separate purge plugin—or manual API calls.

    How to verify your content is actually live

    Don’t trust the WordPress admin. Check the edge.

    The fastest way: open an incognito window and load your post URL. If you see the old version, the cache hasn’t cleared. But that only checks your edge location. If you’re in New York and your readers are in Berlin, you’re not seeing what they see.

    Better: use a CDN cache checker. Tools like RedBot or KeyCDN’s cache checker let you test specific URLs and see cache headers from multiple locations. Look for X-Cache: HIT or CF-Cache-Status: HIT in the response headers. If the Age: header shows a value higher than a few seconds after you published, you’re serving stale content.

    If you’re running Cloudflare, check the dashboard under Caching → Configuration → Purge Cache. You can manually purge individual URLs or the entire cache. If you do this every time you publish, your plugin isn’t working.

    How to fix purge failures before they cost you traffic

    Set your WordPress site URL to match your CDN exactly. Go to Settings → General and make sure WordPress Address (URL) and Site Address (URL) match the protocol and subdomain your CDN uses. If your CDN serves https://www.yoursite.com, both fields should say that. No exceptions.

    Enable wildcard purges or use cache tags. If your CDN supports cache tags (Cloudflare’s Cache-Tag header, Fastly’s Surrogate-Key), configure your caching plugin to tag pages by post ID, category, and archive type. When you update a post, purge by tag instead of URL. This clears every page that references that post, not just the post itself.

    Monitor purge success in your CDN logs. Cloudflare, Bunny, and most CDNs log purge requests. Check the logs weekly. If you see 4xx or 5xx responses, your purge requests are failing. Fix the integration before it compounds.

    Use a staging environment to test purge behavior. Before you publish a high-stakes post—launch announcement, pricing change, time-sensitive news—test the purge flow on staging. Publish the post, wait 30 seconds, check the live URL. If staging purges correctly, production should too. If not, you know before the post goes live.

    If you’re on a host that handles CDN integration for you—BigScoots and other managed WordPress hosts often do—verify that their purge automation covers all the URLs you care about. Ask support which cache layers clear automatically and which require manual intervention.

    When to bypass CDN cache entirely

    Some pages should never be cached at the edge: checkout pages, account dashboards, anything behind a login. Use cache bypass rules in your CDN config to exclude those URLs from edge caching entirely. That way, purge failures can’t hurt conversion flows.

    For time-sensitive content—live event updates, breaking news, flash sales—set a short TTL (60 seconds or less) instead of relying on purge. The CDN will refresh automatically, and you won’t lose traffic if a purge request fails.

    CDN purge isn’t fire-and-forget infrastructure. It’s an API call that fails more often than you think. The operators who verify purge success before sharing a post are the ones whose readers see the right content at the right time.

    Got a caching setup that’s failed you before? Reply and tell us what broke—we’ll cover it in a future issue.

  • Publer’s Auto-Posting Queue: How Priority Slots Work and When to Use Them

    Publer’s Auto-Posting Queue: How Priority Slots Work and When to Use Them

    Publer‘s auto-posting queue doesn’t work like a simple calendar. When you schedule posts across multiple social accounts for the same time slot, the platform uses a priority system to decide what publishes first—and if you don’t configure it correctly, your most important content can get stuck behind low-priority filler.

    This matters when you’re juggling LinkedIn, Twitter, Instagram, and Facebook from a single dashboard. Each network has different API rate limits and posting windows. Understanding how Publer‘s queue prioritizes posts means the difference between coordinated launches and staggered, inconsistent publishing.

    How the Priority Queue Actually Works

    When you schedule multiple posts for the same timestamp, Publer doesn’t publish them simultaneously. It queues them according to three factors: account priority, post type, and API availability.

    Account priority is the setting most operators miss. In your workspace settings, each connected social account has a priority value from 1 to 10. When two posts compete for the same slot, Publer publishes the higher-priority account first. Default priority is 5 for all accounts, which means new users get effectively random ordering.

    Post type matters because different formats take different amounts of time to process. A text-only tweet publishes in under a second. A carousel post with eight images to Instagram takes 15–30 seconds because Publer has to upload media, wait for Instagram’s processing, then attach metadata. If you schedule both at 9:00 AM, the tweet goes live at 9:00:02 and the carousel lands closer to 9:00:35.

    API availability is the wildcard. LinkedIn’s API occasionally throttles requests during peak hours (weekday mornings in US time zones). Facebook’s API can reject posts if your page has recent policy warnings. When Publer hits a rate limit or error, it pauses that account’s queue for 60 seconds and moves to the next priority account. Your post still publishes—it’s just late.

    When to Adjust Priority Settings

    Most solo operators should set LinkedIn to priority 8 or 9, Twitter to 7, and Instagram to 6. LinkedIn drives the most referral traffic for B2B content businesses, so it should publish first when time slots overlap. Twitter comes next because it’s time-sensitive; a tweet posted 45 seconds late misses the algorithmic window for early engagement. Instagram posts have longer shelf lives and benefit less from split-second timing.

    If you’re running coordinated launches—a new course, a product drop, a newsletter issue—set all accounts to the same priority and stagger your scheduled times by two minutes. This forces sequential publishing and prevents API collisions. Schedule LinkedIn for 9:00 AM, Twitter for 9:02 AM, Instagram for 9:04 AM. You’ll see consistent publish times and avoid the queue lottery.

    For daily content that isn’t launch-critical, leave priorities at default and use Publer’s “optimal timing” suggestion feature. It analyzes your audience activity and shifts posts into lower-traffic API windows, which reduces queue conflicts organically.

    The Non-Obvious Tip: Use Priority Slots for Backup Accounts

    Here’s what most people miss: you can connect duplicate accounts with different priority levels to create a fallback system. Connect your primary Twitter account at priority 8, then connect a secondary Twitter account (a brand backup or personal account) at priority 3.

    Schedule the same post to both accounts. If your primary account hits a rate limit, suspension, or API error, Publer skips it and publishes to the backup account automatically. You don’t lose the time slot, and your content still goes live. This setup is especially useful for affiliate promotions or time-sensitive announcements where missing a window costs real money.

    The trade-off: duplicate posts count against your Publer plan limits. The $12/month plan includes 50 scheduled posts across all accounts. If you’re doubling up for redundancy, you hit that cap faster. Upgrade to the $29/month tier for 300 posts, or reserve backup posting for high-value content only.

    What Breaks and How to Fix It

    Publer’s queue log lives under Analytics > Post History. If a post doesn’t publish on time, the log shows the delay reason: API error, media processing timeout, or account priority conflict. Check this weekly, especially if you’re managing client accounts or running paid campaigns.

    The most common failure mode: Instagram carousel posts scheduled during API maintenance windows (usually Sunday mornings, 2–4 AM Pacific). Instagram’s API goes read-only during maintenance, and Publer can’t upload media. Your post fails silently unless you enable push notifications for publishing errors. Turn those on in Settings > Notifications > Publishing Alerts.

    If you’re publishing to Facebook Pages, verify your page token hasn’t expired. Facebook tokens reset every 60 days, and Publer doesn’t always surface the error clearly. You’ll see posts stuck in “Pending” status in the queue, but the error log just says “Authentication failed.” Reconnect your Facebook account in Settings > Social Accounts > Facebook > Reconnect, and past posts will retry automatically.

    Want to see more tool breakdowns like this? Reply with the platform or feature you want dissected next—we’ll add it to the rotation.

    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.

  • AI writing assistants lose your brand voice after 10,000 words

    AI writing assistants lose your brand voice after 10,000 words

    You feed Claude or ChatGPT your style guide, brand voice doc, and three sample articles. The first draft comes back clean. The fifth is still coherent. By draft twelve, you’re rewriting entire sections because the output sounds like a SaaS landing page written by committee.

    The problem isn’t the model. It’s context decay—and most solo operators don’t notice it until they’re deep into a content sprint.

    How context windows actually behave in production

    Modern AI assistants advertise context windows between 100,000 and 200,000 tokens. That sounds massive. In practice, a 2,000-word article with formatting consumes roughly 3,000 tokens. A detailed style guide adds another 1,500. Add three reference articles, a content brief, and iterative edits, and you’re at 15,000 tokens before you hit “generate.”

    The issue isn’t hitting the hard limit. It’s recency bias. AI models weight recent inputs more heavily than older ones. Your brand voice document, uploaded at the start of the session, fades in influence as the conversation grows. By message twenty, the model is prioritizing your last three corrections over the foundational voice rules you set up front.

    This isn’t speculation. Run the same prompt in a fresh session and in a thread with fifteen prior exchanges. The tone, sentence structure, and word choice drift measurably. The fresh session respects your style guide. The deep thread defaults to generic clarity.

    Where the breakdown happens

    Three scenarios accelerate context decay:

    Iterative editing. You ask for a rewrite of paragraph four. Then paragraph seven. Then a punchier intro. Each edit adds tokens. The model starts optimizing for your edits rather than your original brief. If your edits are vague (“make it snappier”), the output drifts toward the model’s base training—usually bland, corporate prose.

    Multi-article sessions. You’re batching content. Article one turns out great. Article two is fine. Article three reads like it was written by a different person. The model is still referencing article one’s context, but it’s now buried under 20,000 tokens of intermediate work. Your style guide is functionally invisible.

    Supplemental instructions mid-thread. You realize the model isn’t using contractions, so you add a note: “Use contractions. Write like a person.” That instruction applies to the current output, but it doesn’t retroactively fix the earlier drift. Worse, it competes with your original style guide, which may have said something more nuanced.

    How to architect around it

    The fix isn’t to abandon AI writing tools. It’s to structure your workflow so the model never has to remember too much at once.

    Start fresh for each piece. Don’t reuse threads across articles. A new session costs you thirty seconds of setup but guarantees your brand voice sits at the top of the context stack. If you’re batching content, open a new chat per article. Yes, you’ll paste your style guide multiple times. That redundancy is weight, not waste.

    Anchor instructions at both ends. Put your core voice rules in the first message and repeat the two most important points in your content brief. Example: if your style guide says “no jargon” and “lead with specifics,” embed those phrases in the article prompt itself. Repetition reinforces priority in the model’s attention mechanism.

    Use system prompts where available. Claude lets you set a system prompt that persists across a conversation. ChatGPT offers custom instructions. Both sit outside the regular context window and don’t decay. Load your brand voice there. Keep it under 300 words—short, imperative statements work better than discursive guidelines.

    Separate editing from generation. If you’re deep into revisions and the tone starts slipping, don’t keep editing in the same thread. Copy the draft into a fresh session, paste your style guide, and ask for a single-pass cleanup. The model will treat your draft as raw input and apply the voice rules uniformly, rather than layering fixes onto fixes.

    What this means for content operations

    If you’re publishing once a week, context decay is invisible. If you’re running a content engine—daily newsletters, multi-author blogs, high-volume SEO plays—it’s the difference between consistent voice and a patchwork of tones.

    The operators who scale AI writing successfully treat it like a stateless function. Each invocation gets the same inputs. No conversation persists long enough to drift. Workflows that rely on “the model will remember” break at volume.

    Track this in your own work. Open your last five AI-generated drafts. Read them in sequence. If draft five sounds meaningfully different from draft one—and you didn’t change your instructions—you’re watching context decay in action.

    One Two Three Send covers the tools and workflows that power solo operations. If you’re running content at scale, subscribe for weekly breakdowns of what works, what breaks, and what costs you time when no one’s watching.

    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.

  • Traffic attribution breaks when you rely on a single UTM parameter

    Traffic attribution breaks when you rely on a single UTM parameter

    You slap a ?utm_source=twitter on a link, post it, and watch Google Analytics log the visits. Job done. Except when you want to know which tweet drove traffic, or whether the thread performed better than the standalone post, you’re looking at an aggregate number that tells you nothing.

    Single-parameter UTM tagging is the norm because it’s fast. But it collapses every variation of a campaign into one bucket. When you run the same link across multiple posts, test different copy, or repost content weeks later, you lose the ability to see what actually worked.

    Why one parameter isn’t enough

    UTM parameters exist in sets: source, medium, campaign, term, and content. Most operators use only source, sometimes medium. That’s enough to tell you traffic came from Twitter or your newsletter, but it won’t help you answer:

    • Did the morning post outperform the evening one?
    • Which subject line variation drove more clicks?
    • Is this week’s guest post pulling better than last month’s?

    Without campaign and content tags, you’re aggregating everything from a source into one line item. If you’re running any kind of test—creative, timing, format—you’re flying blind.

    What to track in each parameter

    Here’s a structure that scales without getting obsessive:

    utm_source: The platform. twitter, linkedin, newsletter, reddit. Keep it consistent. Don’t use Twitter one week and twitter the next—analytics tools are case-sensitive and will split them into separate sources.

    utm_medium: The format or channel type. social, email, paid, organic. This groups sources into broader buckets and makes cross-channel comparisons possible.

    utm_campaign: The specific push or theme. product-launch-june, weekly-roundup-24, black-friday-2026. This is your container for everything related to one coordinated effort.

    utm_content: The variable you’re testing or the specific placement. thread-version-a, header-link, ps-cta. This is where you differentiate two posts in the same campaign.

    Example: You’re running a product launch. You post on Twitter three times over two days—morning thread, afternoon standalone, evening reply-guy style. Tag them:

    • ?utm_source=twitter&utm_medium=social&utm_campaign=product-launch-june&utm_content=morning-thread
    • ?utm_source=twitter&utm_medium=social&utm_campaign=product-launch-june&utm_content=afternoon-standalone
    • ?utm_source=twitter&utm_medium=social&utm_campaign=product-launch-june&utm_content=evening-reply

    Now your analytics show not just that Twitter drove 150 visits, but that the morning thread drove 90, the afternoon post drove 40, and the evening reply drove 20. You know what to repeat.

    Common mistakes that break tracking

    Inconsistent naming. utm_source=Twitter and utm_source=twitter appear as two separate sources. Pick lowercase-with-hyphens and stick to it. Same goes for campaigns: launch_june and launch-june are different.

    Overloading utm_content. Don’t stuff timestamps, user IDs, or session tokens into this field. It’s for human-readable variants, not programmatic tracking. If you need per-user attribution, use a separate query parameter and log it server-side.

    Tagging internal links. Don’t add UTM parameters to links between pages on your own site unless you’re running a specific cross-domain campaign. It resets the session and attributes internal navigation as a new traffic source, which destroys your funnel data.

    Not documenting your taxonomy. Six months from now, you won’t remember whether utm_campaign=june-launch or utm_campaign=product-launch-june was the one you used. Keep a spreadsheet or a Notion page with every active campaign and its naming convention.

    When to simplify

    If you’re posting a link once and never again, a single utm_source is fine. If you’re sharing a static resource—like a media kit or a one-time freebie—you don’t need campaign-level granularity.

    But the moment you’re testing anything—post timing, copy, format, audience segment—you need at least three parameters: source, campaign, and content.

    Traffic attribution only works when you can compare apples to apples. A single UTM parameter turns every variation into the same apple. Add two more, and you’ll finally see what’s working.

    Want more breakdowns like this? Subscribe to One Two Three Send for weekly deep-dives on the tools and tactics that actually move the needle for solo operators.

  • LinkedIn newsletters: when to publish there vs. your own list

    LinkedIn newsletters: when to publish there vs. your own list

    LinkedIn launched native newsletters in 2021, and they’ve quietly become one of the better ways to grow a professional audience without paying for ads. But they’re not a replacement for an owned email list—they’re a different tool with different trade-offs.

    If you’re running a content business, you probably need both. The question is which one gets your best material, and when you should cross-post versus publish exclusive content on each platform.

    How LinkedIn newsletters actually work

    A LinkedIn newsletter is a recurring publication tied to your personal profile or company page. When you publish an issue, LinkedIn notifies subscribers and pushes it into the algorithmic feed for non-subscribers who follow related topics.

    That second part is the big difference. A traditional email newsletter only reaches people who opted in. A LinkedIn newsletter can reach tens of thousands of impressions on the first issue if LinkedIn’s algorithm decides your topic has momentum.

    Subscribers get an email notification (from LinkedIn, not you) and a bell icon alert. You don’t own the email addresses. You can’t export them. You can’t segment, tag, or automate follow-ups. LinkedIn owns the relationship.

    Publishing cadence matters more here than on a self-hosted list. LinkedIn rewards consistency—weekly or biweekly posts perform better than monthly because the algorithm favors active publishers. Miss three weeks and your next issue will get buried.

    When LinkedIn newsletters win

    If you’re starting from zero and need fast traction in a B2B niche, LinkedIn newsletters are hard to beat. You can get your first 500 subscribers in a month without spending a dollar, especially if you’re writing about SaaS, freelancing, recruiting, or professional development.

    The platform is also ideal for reach-focused content that doesn’t require a hard conversion. Thought leadership posts, contrarian takes, and industry commentary all perform well because LinkedIn’s feed amplifies debate and engagement.

    One operator I know runs a DevOps newsletter entirely on LinkedIn. He hit 12,000 subscribers in six months, gets 40–60 comments per issue, and converts readers into consulting clients through DMs. He’s never sent a traditional email newsletter and doesn’t plan to.

    His model works because his business relies on visibility and inbound leads, not product sales or affiliate revenue. LinkedIn’s algorithm does the distribution work for him.

    When your own list wins

    If you’re monetizing through sponsorships, affiliate links, paid subscriptions, or product launches, you need an owned list. LinkedIn doesn’t let you run third-party ads in newsletters, and their affiliate link policies are murky at best.

    You also can’t A/B test subject lines, track click-through rates by segment, or automate a welcome sequence. LinkedIn’s analytics show opens, clicks, and basic demographics, but you can’t funnel readers into a product waitlist or tag them based on behavior.

    Control matters more as your business matures. Platforms change policies, shut down features, or deprioritize content types without warning. In 2023, LinkedIn throttled newsletter reach for accounts that cross-posted identical content from Substack or Beehiiv. The algo spotted duplicate intros and punished them.

    If your revenue depends on email, you can’t afford that risk. One algorithm shift shouldn’t kill your income.

    The hybrid approach that works

    Most operators I know who do this well publish different content on each platform. LinkedIn gets the high-level, debate-worthy stuff—opinion pieces, trend commentary, and open-ended questions. The owned list gets tactical how-tos, product updates, and anything with a monetization angle.

    You can also use LinkedIn as a top-of-funnel tool. Publish a condensed version of your best content there, then link to the full piece on your site or in your email archive. Include a low-friction CTA at the end: “I send a deeper dive every Thursday—join 3,200 operators here.” Link to your signup page.

    That approach works because LinkedIn subscribers are already in consumption mode. They’re not cold traffic. A 2–5% conversion rate from LinkedIn newsletter subscriber to owned-list subscriber is realistic if your CTA is clear and the value proposition is obvious.

    One workflow: write your main newsletter issue in Beehiiv or MailerLite, pull the intro and one key section, rewrite it for LinkedIn’s feed tone (more casual, more debate-friendly), publish it as a LinkedIn newsletter, and link back to the full version. Track conversions in your email platform to see if the crossover is worth the extra 20 minutes per week.

    Don’t post identical content on both. LinkedIn’s algorithm will bury it, and your email subscribers will feel like they’re reading reruns.

    Want to compare email platforms for your owned list? We covered ConvertKit vs. Beehiiv vs. Substack in detail last week, including pricing breakpoints and feature gaps that matter for monetization.

    Platform lock-in is real

    The biggest long-term risk with LinkedIn newsletters is that you’re building on rented land. LinkedIn could sunset the feature, change the notification system, or require a paid tier to reach your own subscribers. It’s happened before on other platforms.

    If LinkedIn newsletters are your primary audience channel, set a reminder every quarter to test a migration offer. Send one issue with a clear ask: “I’m testing a standalone email list—if you want these posts delivered outside LinkedIn, sign up here.” Track how many people convert. If it’s under 1%, you’re locked in. If it’s over 5%, you have options.

    The goal isn’t to abandon LinkedIn—it’s to make sure you’re not hostage to it.

    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.

  • MailerLite’s Auto-Resend Feature: How It Works and When to Use It

    MailerLite’s Auto-Resend Feature: How It Works and When to Use It

    MailerLite offers a feature most solo operators ignore: auto-resend to non-openers. You send a campaign, wait a set number of days, then MailerLite automatically resends the same email to everyone who didn’t open it the first time—with a new subject line you provide.

    It sounds like free engagement. Sometimes it is. Sometimes it’s a waste of deliverability budget. Here’s how to know the difference.

    How Auto-Resend Works

    When you schedule or send a campaign in MailerLite, you’ll see a checkbox: “Resend this campaign to non-openers.” Enable it, and you choose:

    • How many days to wait before resending (minimum 1 day, maximum 10)
    • A new subject line for the resend
    • Whether to resend to people who didn’t open or didn’t click (two separate filters)

    MailerLite tracks opens via a 1×1 pixel embedded in the email. If that pixel doesn’t load within your wait window, the subscriber gets the resend. The body content stays identical; only the subject line changes.

    The feature is available on all MailerLite plans, including the free tier (up to 1,000 subscribers and 12,000 emails per month). No extra charge per resend—it just counts against your monthly send quota.

    When Auto-Resend Actually Works

    This feature pays off in three scenarios:

    Time-sensitive content with a narrow window. If you’re promoting a webinar, sale, or limited offer, a resend 2–3 days before the deadline can recover 8–15% additional opens. The urgency justifies the repeat send, and the new subject line can emphasize scarcity (“Last chance” vs. your original angle).

    Evergreen content you’re confident in. If your original open rate was below 30% and you believe the content itself is strong—tutorial, case study, resource roundup—a resend with a clearer or more specific subject line often pulls another 5–10% open rate. You’re not pestering; you’re giving the email a second chance to surface in a cleaner inbox.

    Large lists with inconsistent engagement. If you have 5,000+ subscribers and your median open rate sits around 25–35%, auto-resend becomes a volume play. Even a modest 8% lift on the resend adds hundreds of opens you wouldn’t have captured otherwise, and the deliverability risk is minimal if your sender reputation is healthy.

    When to Skip It

    Auto-resend backfires when:

    Your original subject line wasn’t the problem. If your open rate is consistently above 40%, the issue isn’t visibility—it’s relevance or timing. Resending won’t fix that. You’ll just train subscribers to expect duplicates and ignore both.

    You send frequently. If you publish three or more emails per week, a resend starts to feel like spam. Subscribers who didn’t open the first time likely weren’t interested, and showing up again 48 hours later erodes trust faster than it recovers engagement.

    You’re resending promotional content repeatedly. If every sales email gets auto-resent, subscribers notice the pattern. It signals desperation, and it trains them to wait for the resend (or unsubscribe). Reserve auto-resend for your strongest content, not every broadcast.

    One Non-Obvious Tip

    Most operators test two subject lines by running A/B splits on the initial send, then using the winner for the resend. Flip that logic.

    Send your safer, clearer subject line first—the one that accurately describes what’s inside. Then use the resend to test a riskier, more curiosity-driven or emotional angle. If it flops, you’ve only burned the non-openers. If it works, you’ve discovered a subject-line style that breaks through inbox noise, and you can apply that learning to future campaigns.

    This approach also avoids the common mistake of making the resend subject line worse than the original. I’ve seen operators rewrite a specific, compelling subject into a vague one just to make it “different.” The resend open rate craters, and they blame the feature instead of the execution.

    MailerLite’s auto-resend costs you nothing but send volume. If you’re already paying for a plan and sitting below your monthly limit, the feature is pure upside—as long as you use it strategically, not reflexively. Test it on one high-value campaign, measure the lift, and decide from there.

    Want more breakdowns like this? Subscribe to One Two Three Send for weekly deep-dives on the tools and tactics that actually move the needle for solo operators.

  • Analytics dashboards hide more than they reveal

    Analytics dashboards hide more than they reveal

    Open Google Analytics, Plausible, or Fathom right now. You’ll see pageviews, sessions, bounce rate, referrers. Clean charts. Tidy numbers. Everything you need to know about your traffic.

    Except you’re looking at a summary of a summary of a summary. The dashboard is a lossy compression algorithm designed to make patterns visible—and in doing so, it hides the outliers, the edge cases, and the signal buried in the noise.

    If you’re running a content business, those hidden details are where the decisions live.

    What the default view doesn’t show you

    Most analytics dashboards aggregate by default. They show you total sessions, average time on page, top landing pages. That’s fine for a monthly report, but it flattens the distribution.

    Here’s what vanishes:

    • Single-page sessions that converted. A reader lands on your pricing page, scrolls to the bottom, clicks “subscribe,” and leaves. Bounce rate: 100%. Value: high. The dashboard flags it as a failure.
    • Referrer context beyond the domain. You see “twitter.com” in your referrer log. You don’t see which tweet, which reply thread, or whether it came from a quote-tweet with 800 impressions or a reply buried three levels deep.
    • Time-on-page outliers. Your median time on page is 1:20. One reader spent 22 minutes. Another spent four seconds. The average says nothing about either.
    • Entry and exit paths that don’t follow your funnel. You assume readers land on your homepage, browse, then subscribe. Half of them land on a three-year-old post, read two paragraphs, and subscribe from the inline CTA. Your dashboard doesn’t highlight that path unless you go looking.

    Default dashboards are built for SaaS companies with linear funnels. Content businesses don’t have linear funnels. Readers enter from anywhere, stay as long as they want, and convert when something clicks. The dashboard doesn’t map that.

    The data you need to export manually

    If you want to see what’s actually happening, you need to pull raw session logs or build custom reports. Here’s what to look for:

    Session duration distribution, not average. Export time-on-site data and chart it as a histogram. You’ll see three clusters: under ten seconds (accidental clicks or bots), 30 seconds to two minutes (skimmers), and five minutes-plus (engaged readers). The third group is your real audience. The dashboard average blends all three into a number that describes no one.

    Conversion paths, not just conversion rate. Most analytics tools let you build a funnel report. Set it to show all paths, not just the primary one. You’ll find readers who convert after visiting your about page, your uses page, and a random blog post from 2023. That’s not a broken funnel—it’s how trust builds in a content business.

    Referrer URLs, not referrer domains. If you’re using GA4, enable the full referrer URL in your data stream settings. If you’re using Plausible or Fathom, export your referrer data and sort by frequency. You’ll see which specific tweets, Reddit threads, or Hacker News comments are sending traffic. That tells you what to do more of.

    Exit pages for engaged sessions only. Filter your exit-page report to sessions longer than two minutes. You’ll see where your best readers leave. If they’re exiting from your pricing page, your CTA might be unclear. If they’re exiting from a post with no CTA, you’re leaving conversions on the table.

    When to ignore the dashboard entirely

    Sometimes the dashboard is wrong in a way that matters.

    If you’re running a small operation—under 10,000 sessions a month—your sample size is too small for statistical patterns to emerge. A single Reddit post can double your traffic for a day and skew your monthly average. The dashboard will show a spike, then a drop, and suggest you’re losing momentum. You’re not. You just had one good day.

    If you’re publishing sporadically, your traffic will look like a sawtooth. The dashboard will show declining engagement because it assumes consistent output. It doesn’t know you took two weeks off.

    If you’re testing a new traffic channel—say, you’re experimenting with Pinterest or Threads—the dashboard will bury it under “other” until it hits 5% of total traffic. You won’t see early traction unless you filter for it.

    In all three cases, the dashboard is technically accurate. It’s just not useful.

    What to do instead

    Set up three custom reports and review them monthly:

    • A session-duration histogram, filtered to organic and referral traffic only.
    • A conversion-path report showing all routes to subscription, not just the top funnel.
    • A referrer-URL export, sorted by engaged sessions (two minutes or longer).

    These three views will tell you more about your audience than any pre-built dashboard. They take ten minutes to set up and five minutes to review. The insight-to-effort ratio is better than anything else in your analytics stack.

    Want more breakdowns like this? Subscribe to One Two Three Send for weekly deep dives on the tools and tactics that actually move the needle for solo operators.

  • WordPress multisite migration: what breaks and what doesn’t

    WordPress multisite migration isn’t the same as moving a single-site install. The network architecture means your database holds cross-site references, your media library spans domains, and your DNS has to route traffic through the primary domain before handing off to subsites.

    If you’ve ever moved a multisite network to a new host and watched half your images vanish or login redirects break, you know the pain. Here’s what actually breaks, what survives the move, and how to fix the common failure points before they cost you traffic.

    URL mappings break first

    Multisite stores site URLs in wp_blogs and wp_site tables. When you migrate, your old domain references stay hardcoded unless you run a search-and-replace across the network database.

    If you’re running subdomain multisite (like site1.yourdomain.com), every subsite has its own domain entry in wp_blogs. A standard WP migration plugin won’t catch these—it only updates siteurl and home in wp_options for the primary site.

    Run a network-wide search-and-replace using WP-CLI’s search-replace command with the --network flag, or use a plugin like Better Search Replace in network mode. Target the old domain string and replace it with the new one across all tables. Don’t skip serialized data—WordPress stores arrays and objects in the database, and a partial string replacement corrupts them.

    Media library paths don’t update automatically

    Multisite stores uploaded files in /wp-content/uploads/sites/{site_id}/ directories. When you migrate, the files move with the server, but image URLs in post content and media library metadata still point to the old domain.

    Your search-and-replace will catch most of these if you’re thorough. But if you’re moving from HTTP to HTTPS, or changing the subdirectory path (like moving from /blog/ to root), you’ll have orphaned image references that don’t render.

    Check wp_posts.guid and wp_postmeta for _wp_attached_file and _wp_attachment_metadata keys. These hold the full image paths and need manual correction if your directory structure changed. A broken guid won’t stop images from displaying, but it will break media library searches and attachment page URLs.

    Subdomain DNS has to route through the primary domain

    If you’re running subdomain multisite, your DNS needs a wildcard A record pointing *.yourdomain.com to your server IP. When you migrate hosts, that wildcard has to update to the new IP—and if your DNS propagation is slow, subsites will be unreachable even after the primary domain resolves.

    Check your DNS panel and confirm the wildcard record exists and points to the correct IP. If you’re using Cloudflare or another proxy, make sure the wildcard is set to DNS only (gray cloud) during migration, not Proxied (orange cloud). Proxied wildcard records can break subsite routing if the SSL certificate doesn’t cover all subdomains.

    If you’re moving to a managed WordPress host like BigScoots, ask support whether they handle wildcard DNS automatically. Some hosts provision it; others require manual setup.

    Plugin network activation states don’t transfer cleanly

    Multisite lets you activate plugins network-wide or per-site. When you migrate, the wp_sitemeta table holds network activation data, and wp_{site_id}_options tables hold per-site activation.

    If you’re moving between hosts with different PHP versions or server configurations, plugins that worked network-wide on the old host may fail silently on the new one. Check the active_sitewide_plugins key in wp_sitemeta after migration and deactivate any plugins that throw errors in the WordPress admin.

    Some plugins—especially caching and security plugins—store server paths in their settings. If your new host uses a different document root (like /var/www/html/ instead of /home/username/public_html/), those plugins will break until you regenerate their config files.

    What actually survives the move

    Your post content, user accounts, and plugin settings all migrate cleanly if you’re using a proper database export. The wp_users and wp_usermeta tables are network-global, so user logins work across all subsites immediately after the move.

    Theme files and uploads transfer intact if you copy the entire /wp-content/ directory. Just make sure file permissions are set correctly on the new host—644 for files, 755 for directories. If your new host uses a different user/group (like www-data instead of nobody), you’ll need to chown the files or uploads will fail.

    Test before you flip DNS

    Before you point your domain to the new host, test the migration using your server’s temporary URL or by editing your local /etc/hosts file to map your domain to the new IP.

    Log in to the network admin, visit a few subsites, upload a test image, and check whether plugins activate correctly. If anything breaks, you can fix it without taking the live site offline.

    Once you’re confident, update your DNS A records, wait for propagation, and flush any page caches. Multisite migrations take longer than single-site moves, but if you catch the URL mappings, media paths, and DNS routing, the network will come up clean.

    Got a multisite migration story? Reply with what broke for you—we’ll cover edge cases in a future issue.