Author: onetwothreeadmin

  • AI summarization tools chop context you still need—here’s what gets lost

    AI summarization tools chop context you still need—here’s what gets lost

    AI summarization tools chop context you still need—here's what gets lost
    Photo: DataBase Center for Life Science (DBCLS) via Wikimedia Commons (CC BY 4.0)

    AI summarization tools promise to collapse 3,000-word articles into 300-word digests. They work—but they work by making editorial choices you didn’t authorize. For solo operators running content-driven businesses, those choices often discard the exact context that makes source material useful.

    If you’re summarizing competitor analysis, customer research, or technical documentation to brief yourself or your team, understanding what AI summarizers routinely drop will save you from acting on incomplete information.

    What gets cut first: hedges, conditions, and attribution

    Most summarization models prioritize declarative statements and strip conditional language. A source sentence like “In markets where CAC exceeds $80, paid social often underperforms organic by 15–20% according to three operators we surveyed” becomes “Paid social underperforms organic.”

    Three critical pieces disappear: the $80 CAC threshold, the 15–20% range, and the sample size. You’re left with a claim that sounds absolute but was contextual. If your CAC is $40, the original finding may not apply—but the summary won’t tell you that.

    Source attribution drops even faster. Summarizers treat citations and hedges as filler. “According to Databox’s Q2 report” becomes invisible. If you later want to verify a claim or check the methodology, you’ll have to re-read the original—which defeats half the purpose of summarizing in the first place.

    Nuance flattens into binary claims

    Summarization models favor simplicity. A paragraph explaining that email open rates vary by send time, audience segment, subject line length, and day of week might reduce to “Send time affects open rates.” Technically true. Operationally useless.

    This flattening is most dangerous when summarizing case studies or operator interviews. A founder saying “We tried affiliate marketing for six months, saw no traction, then switched our link placement strategy and 3x’d revenue in 90 days” often summarizes to “Affiliate marketing worked after six months.” The strategy shift—the actual insight—vanishes.

    If you’re summarizing content to extract takeaways for your own projects, you need the conditions and the pivots. The summary gives you the outcome without the mechanism.

    Edge cases and exceptions disappear

    AI summarizers optimize for the majority case. Exceptions, outliers, and “but if you’re in X situation, do Y instead” clauses get trimmed as noise.

    A guide explaining that WordPress caching plugins speed up most sites but break membership paywalls and logged-in user experiences will summarize to “Caching plugins speed up WordPress.” If you run a membership site, you just got advice that will break your business.

    The same happens with tool recommendations. An article comparing three email platforms—two general-purpose and one for e-commerce operators with Shopify integrations—might summarize without preserving the Shopify caveat. You’ll see “Platform A is cheaper” without the asterisk that it only works if you don’t need e-commerce features.

    When to summarize and when to skim yourself

    AI summarization works well for news aggregation, surface-level topic scanning, and filtering content you’ll never revisit. If you’re reading ten competitor blogs to check for overlapping topics, a summarizer saves time.

    Skip the summarizer when you’re extracting decision-critical details: pricing research, technical setup guides, operator case studies with metrics, or any content where the “how” matters as much as the “what.” For those, skim the original yourself or use the summarizer as a first pass, then read the sections it flags as important.

    If you do summarize, keep the original link in your notes. Tools like Claude let you upload documents or paste long text for summarization—useful when you control the prompt and can ask it to preserve conditions, citations, and ranges. Default summarizers in browser extensions and read-it-later apps rarely let you tune their behavior.

    The time you save summarizing often gets spent re-reading later when you realize a key detail is missing. For high-stakes decisions, read the source. For everything else, summarize—but know what you’re trading away.

    Want more tools and workflows for solo operators? Subscribe to One Two Three Send for weekly breakdowns of how online-business software actually works.

    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 automation filters stack in reverse order—here’s how

    ConvertKit’s visual automation builder looks intuitive—drag a few boxes, connect some arrows, add a filter or two, and you’re done. But there’s a non-obvious quirk in how the platform evaluates filter conditions that trips up even experienced operators: filters stack in reverse order.

    If you’ve ever set up an automation rule with multiple conditions and watched subscribers either flood through when they shouldn’t or fail to trigger when they should, this is the mechanic that explains it.

    How filter stacking actually works

    ConvertKit evaluates conditions from the bottom of your filter list upward, not top-to-bottom like you read. If you add three conditions—say, “has tag A,” “does not have tag B,” and “signed up more than 7 days ago”—the platform checks the bottom condition first, then works its way up.

    This matters when you’re using AND/OR logic. A rule that reads clearly in your head when stacked top-to-bottom can behave completely differently when evaluated in reverse.

    Here’s a concrete example: you want to send a product launch email only to subscribers who opened your last broadcast and don’t already own the product. You add two filters:

    • Top filter: Opened broadcast “Pre-launch Teaser”
    • Bottom filter: Does not have tag “Customer”

    ConvertKit checks the “Customer” tag first. If that passes, it checks the open. But if you’re using OR logic somewhere in the stack, the sequence can fire for anyone without the tag—even if they never opened the email.

    The fix is to reverse your mental model: build filters from the bottom up, with your most restrictive condition at the top of the list.

    When this breaks automations silently

    The stacking order doesn’t throw an error. Your automation just underperforms, and you won’t know why unless you manually trace a few subscriber paths.

    Common failure modes:

    • Welcome sequences fire for existing customers. You added a “new subscriber” filter at the top, but an OR condition lower in the stack lets tagged users through.
    • Upsell emails go to people who already bought. You filtered for “does not have tag X,” but a date-based condition evaluated first and passed everyone through.
    • Re-engagement campaigns trigger immediately. You set “inactive for 30 days” at the top, but ConvertKit checked a different condition first and started the sequence early.

    These bugs don’t show up in the builder UI. The visual flow looks correct. But the logic runs backward.

    How to audit your existing automations

    Open each automation rule and list your filters on paper, bottom to top. Then walk through the logic as ConvertKit would execute it. Ask:

    • Does the bottom condition pass the right people?
    • If yes, does the second-to-bottom refine or expand that group?
    • Are any OR statements letting in subscribers you didn’t intend?

    If you’re using more than three filters, consider splitting the automation into two rules. ConvertKit’s AND/OR toggle applies to the entire stack, so complex logic gets hard to reason about fast.

    For high-stakes sequences—product launches, course enrollments, refund follow-ups—test with a single subscriber first. Tag yourself, trigger the automation manually, and confirm you land in the right sequence at the right time.

    One non-obvious workaround

    If you need granular control and can’t get the filter stack to behave, move your logic into tags instead of filters. Create a dedicated tag that represents the exact subset of subscribers you want to target, then use a separate automation to apply that tag based on behavior.

    For example, instead of filtering for “opened email A AND does not have tag B AND signed up more than 7 days ago,” create a tag called “Launch-Eligible” and use one automation to apply it when all three conditions are true. Then trigger your launch sequence with a single filter: “has tag Launch-Eligible.”

    It’s an extra step, but it eliminates ambiguity. You’re offloading the logic from ConvertKit’s filter stack into a tagging rule you control, and the sequence itself becomes a simple on/off switch.

    This approach also makes debugging faster. If someone didn’t receive the email, you check whether they have the tag. If they don’t, you trace back through the tagging automation to see which condition failed.

    ConvertKit’s automation builder is powerful, but the reversed filter evaluation is a sharp edge. Once you know how it works, you can design around it. Until then, it’s easy to ship a sequence that looks right but runs wrong.

    Got a ConvertKit automation that’s misbehaving? Reply with the filter setup—I’ll walk through how the platform is likely evaluating it.

  • Attribution windows shorter than your sales cycle break conversion tracking

    Attribution windows shorter than your sales cycle break conversion tracking

    Attribution windows shorter than your sales cycle break conversion tracking
    Photo: Haymillefolium via Wikimedia Commons (GPLv3)

    Attribution windows define how long a platform remembers where a visitor came from before they convert. Google Analytics defaults to 90 days for most models. Facebook Ads dropped to 7-day click, 1-day view in 2021 and hasn’t budged. Most affiliate networks sit at 30 days. And if you’re running a content business with a considered purchase—a course, a yearly subscription, a high-ticket consulting package—there’s a good chance your actual sales cycle is longer than every attribution window you’re using.

    When that happens, you stop seeing where revenue actually comes from. You start making decisions on incomplete data. And you end up over-investing in channels that look good on a short clock while starving the ones that drive long-term growth.

    What attribution windows actually control

    An attribution window is the trailing period during which a platform will connect a conversion back to a traffic source. If someone clicks your Facebook ad, thinks about it for eight days, then subscribes, Facebook won’t count that conversion—because its click attribution window is seven days. The sale still happened. You just can’t see what caused it.

    This matters less for impulse purchases. If you’re selling a $19 ebook and most people buy within an hour of landing on the page, a 7-day window is fine. But if you’re selling a $500 course, and your average buyer reads four articles, downloads a lead magnet, gets three emails, and converts 18 days later, that 7-day window is functionally useless.

    The result: you see “direct” or “none” as your top conversion source, because the original referral aged out. You assume organic works. You double down on SEO. Maybe it does work—but you’re guessing, because the system threw away the breadcrumb trail halfway through.

    How to audit your funnel against your windows

    Pull your actual time-to-conversion data. In Google Analytics 4, go to Reports > Engagement > Conversions, then add a secondary dimension for “Days to conversion.” Export it. Calculate the median and 75th percentile. That’s your real sales cycle.

    Now compare it to every attribution window you rely on:

    • Google Analytics 4: 90 days for data-driven attribution by default, but many operators still use last-click models with shorter windows
    • Facebook/Instagram Ads: 7-day click, 1-day view
    • LinkedIn Ads: 90-day click by default, but viewthrough is much shorter
    • Affiliate platforms: typically 30–90 days depending on the network
    • Email platforms: effectively infinite if you’re tracking via UTM, but many operators rely on platform-native conversion tracking that resets on re-engagement

    If your 75th percentile time-to-conversion is longer than your shortest attribution window, you’re losing signal. And because short-window platforms tend to be the ones with the biggest budgets (paid social), you’re probably misallocating spend.

    Fixing it without ripping out your stack

    You can’t change Facebook’s attribution window. But you can layer your own. The simplest fix: use a dedicated attribution tool that tracks first touch, last touch, and everything in between with a custom window. Tools like Hyros, Attributer, and Wicked Reports let you set windows as long as you want and tie them to actual revenue, not just platform-reported conversions.

    If you’re not ready to pay for another SaaS layer, extend your own tracking. Use UTM parameters religiously, store them in a cookie or your CRM with a long expiration, and tie conversions back manually in a spreadsheet or your database. It’s not elegant, but it works. Set your cookie to expire at 180 days if your real sales cycle is 60–90. Give yourself margin.

    Another option: shift budget toward channels with longer native windows. Google Search and SEO have effectively infinite attribution if someone converts in-session. Email works the same way. Organic social is harder to track, but if you’re using link shorteners with your own UTMs and a long cookie, you control the window.

    The worst move is to keep running paid social, see “direct” conversions climb, assume brand is working, and never connect the dots. That’s not brand lift. That’s attribution collapse.

    When to care and when to ignore it

    If your median time-to-conversion is under 7 days and you’re running straightforward offers, this doesn’t matter. Optimize in-platform, trust the numbers, move on.

    But if you’re selling anything that requires consideration—courses, memberships, coaching, SaaS annual plans—or if you’re seeing a growing share of “direct” traffic that converts better than named sources, your attribution windows are probably lying to you. Fix the measurement before you fix the marketing.

    Want more breakdowns like this? Subscribe to One Two Three Send and get one operator-focused deep-dive in your inbox every week.

  • Most operators track too many social platforms—here’s the cutoff

    Most operators track too many social platforms—here’s the cutoff

    Most operators track too many social platforms—here's the cutoff
    Photo by Joel Rivera-Camacho on Unsplash

    The default advice for growing an online business is to be everywhere: Twitter, LinkedIn, Instagram, Threads, Bluesky, TikTok. Post daily. Engage relentlessly. Cross-promote.

    In practice, most solo operators and small teams spread themselves so thin across platforms that they can’t tell which channels actually deliver. They post sporadically, track inconsistently, and burn hours context-switching between apps with no clear return.

    The contrarian take: you should be active on two social platforms, maybe three. Any more than that and you’re optimizing for presence instead of results.

    The cost of multi-platform distribution

    Every platform you maintain has a real time cost. You need to:

    • Adapt content format and tone for each audience
    • Monitor replies, DMs, and mentions
    • Track referral traffic and conversions separately
    • Stay current on algorithm changes and feature rollouts
    • Manage posting schedules that don’t overlap poorly

    A single post on LinkedIn might take 10 minutes to write and format. The same core idea reshaped for Twitter threads, Instagram carousels, and TikTok scripts can easily consume two hours. If you’re posting three times a week across four platforms, that’s 24 hours a month just on content creation—before engagement, before analytics.

    And unlike email, where you own the relationship, social platforms can change reach overnight. You’re renting attention, and the lease terms shift without notice.

    How to pick your two platforms

    Start with where your revenue actually comes from. Open your analytics tool—Google Analytics, Fathom, Plausible, whatever you use—and filter traffic sources for the last 90 days. Look at:

    • Sessions from each social platform
    • Conversion rate (email signups, purchases, course enrollments)
    • Time on site—are visitors sticking around or bouncing?

    Most operators discover that 80% of their social-driven conversions come from one or two platforms. Often it’s LinkedIn for B2B, Twitter for tech audiences, or Instagram for visual products. The other four platforms deliver sporadic traffic that rarely converts.

    If you don’t have 90 days of data, run a 30-day test. Post consistently on your current platforms and track everything with UTM parameters (?utm_source=twitter&utm_medium=social&utm_campaign=july). The platform that delivers qualified traffic wins. The rest are candidates for shutdown.

    What about discovery and reach?

    The common objection: “But I need to be everywhere for discovery. What if my audience is on Platform X?”

    Discovery is overrated for most online businesses. If you’re running a newsletter, a course, or a productized service, your growth comes from being consistently valuable in one place, not sporadically present in six. A weekly LinkedIn post that gets 40 comments and five email signups beats a daily TikTok habit that generates 2,000 views and zero conversions.

    The operators who grow fastest pick one primary platform and one backup. Primary gets 70% of effort: original content, deep engagement, network building. Backup gets 30%: reposts, highlights, low-effort syndication. Everything else gets abandoned or automated into oblivion.

    Tools like Publer can help with cross-posting if you want a minimal presence elsewhere, but even then, you’re better off focusing energy than fragmenting it.

    When to add a third platform

    Add a third platform only when:

    • Your two primary channels consistently deliver 20+ conversions per month each
    • You have a specific, proven audience segment that only exists on the new platform
    • You can hire or delegate content creation so your personal time doesn’t increase

    Until then, double down on what works. A single platform with deep engagement and clear attribution beats shallow presence across the entire social web.

    If this resonated, subscribe to One Two Three Send—we cover the infrastructure and tooling decisions that actually move the needle for solo operators and small teams.

    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 image optimization plugins: lazy load vs. CDN rewrite logic

    WordPress image optimization plugins: lazy load vs. CDN rewrite logic

    WordPress image optimization plugins: lazy load vs. CDN rewrite logic
    Photo by sarah b on Unsplash

    Most WordPress sites run at least one image optimization plugin. Many run two or three at once: a lazy load plugin, a CDN rewrite plugin, and maybe an image compression tool. The problem is that these plugins don’t coordinate—they stack transformations on top of each other, and sometimes those transformations conflict.

    The result isn’t always visible. Your images might load fine on desktop, then break on mobile. Or they load, but the CDN never serves them. Or lazy load fires twice, delaying the render by an extra second.

    Here’s how lazy load and CDN rewrite logic actually work, where they collide, and how to configure them so they don’t cancel each other out.

    Lazy load rewrites your image tags before the page renders

    Lazy load plugins work by intercepting the HTML output buffer just before WordPress sends the page to the browser. They scan for <img> tags, rewrite the src attribute to a placeholder (often a transparent 1×1 GIF or inline SVG), and move the real image URL into a data-src attribute. A JavaScript library watches the viewport and swaps data-src back into src when the image is about to scroll into view.

    That rewrite happens after WordPress generates the HTML, but before it gets sent to the browser. Most lazy load plugins hook into the the_content filter or the final output buffer, which means they’re one of the last things to touch the page.

    The timing matters, because CDN rewrite plugins also hook into the output buffer—and they’re looking for image URLs to rewrite.

    CDN rewrite plugins replace your domain with the CDN endpoint

    A CDN rewrite plugin scans the same HTML output buffer and looks for any URL pointing to your domain. When it finds an image URL like https://yourdomain.com/wp-content/uploads/image.jpg, it replaces the domain with your CDN endpoint: https://cdn.yourdomain.com/wp-content/uploads/image.jpg or https://abc123.cloudfront.net/image.jpg.

    That rewrite is simple: it’s a string replacement. The plugin doesn’t parse the HTML into a DOM tree—it just searches for your domain and swaps it out.

    But if the lazy load plugin has already moved the real image URL into data-src, the CDN plugin might not find it. Some CDN plugins only rewrite src attributes. Others rewrite both src and data-src, but the order matters.

    When the wrong plugin runs first, images don’t serve from the CDN

    If the lazy load plugin runs before the CDN rewrite plugin, the CDN plugin sees src="data:image/svg+xml…" and data-src="https://yourdomain.com/image.jpg". If it’s only configured to rewrite src, it skips the image. The image loads from your origin server, not the CDN.

    You won’t see an error. The image still loads. But you’re paying for CDN bandwidth and getting none of the latency benefit.

    If the CDN plugin runs before lazy load, it rewrites the src to the CDN URL, then lazy load moves that CDN URL into data-src and replaces src with a placeholder. That works—but only if the lazy load plugin doesn’t strip attributes it doesn’t recognize.

    How to check which plugin runs first

    View the page source in your browser. Don’t use the inspector—view the raw HTML that the server sends. Look for an <img> tag and check three things:

    • Does the src attribute point to a placeholder or a real image?
    • Does the data-src (or data-lazy-src) attribute exist, and does it point to your CDN or your origin domain?
    • Are there any other data- attributes you don’t recognize? Some plugins add their own.

    If data-src points to your origin domain, lazy load is running before CDN rewrite, and the CDN isn’t serving those images.

    If data-src points to your CDN, the order is correct—but you should also check the Network tab in DevTools to confirm the image actually loads from the CDN and doesn’t 404.

    The fix: force CDN rewrite to run last, or use native lazy loading instead

    Most WordPress lazy load plugins let you set a priority for the output buffer filter. Lower numbers run earlier. If your CDN plugin priority is set to 10 and your lazy load plugin is also 10, WordPress runs them in the order they were loaded—which is unpredictable.

    Set your CDN rewrite plugin priority to something high, like 99 or 999, so it runs after lazy load. That way it catches both src and data-src attributes.

    Alternatively, skip the lazy load plugin entirely and use native browser lazy loading. Add loading="lazy" to your <img> tags. WordPress has done this by default since version 5.5 for any image in post content. Native lazy loading doesn’t rewrite attributes, so there’s no conflict with CDN plugins.

    The tradeoff: native lazy loading doesn’t let you control the threshold (how far from the viewport the image loads), and it doesn’t work in older browsers. But for most solo operators, that’s fine. The performance gain from avoiding two competing JavaScript libraries outweighs the loss of fine-grained control.

    Want more WordPress performance breakdowns like this? Subscribe to One Two Three Send—one article like this, every day, in your inbox.

  • Newsletter subscriber churn happens in silence—measure it weekly

    Newsletter subscriber churn happens in silence—measure it weekly

    Newsletter subscriber churn happens in silence—measure it weekly
    Photo by Brett Jordan on Unsplash

    Most newsletter operators check their unsubscribe count once a month, usually when they’re reconciling their ESP bill or prepping a performance report. By then, any spike is historical. You can’t remember what you sent three Tuesdays ago, let alone correlate a content decision with a drop in subscribers.

    Churn happens in real time. Your ability to learn from it degrades exponentially with delay.

    If you want to understand what makes readers leave—and what keeps them—you need to measure churn weekly, ideally within 48 hours of each send. Here’s how to set that up, what benchmarks matter, and what silent churn actually costs you.

    What churn rate actually measures

    Churn rate is the percentage of your list that unsubscribes (or gets suppressed) in a given period. The formula is simple:

    Churn rate = (unsubscribes + bounces + spam complaints) / total subscribers at start of period

    Most platforms show you gross unsubscribe count. That’s useless without context. A list of 500 losing 5 subscribers is a 1% churn rate. A list of 10,000 losing 50 is 0.5%. The smaller list has double the problem.

    For solo operators and small teams, a healthy monthly churn rate sits between 0.5% and 2%. That translates to roughly 0.1%–0.5% per send if you’re mailing weekly. Above 0.75% per send, something’s broken—either your content, your targeting, or your acquisition source.

    But monthly averages hide the story. A 2% monthly churn could mean steady 0.5% weekly attrition, or it could mean one catastrophic send at 8% followed by three quiet weeks. You need the breakdown.

    Set up a weekly churn dashboard

    Most ESPs don’t surface per-send churn in an obvious place. You’ll need to pull it manually or script it.

    In Beehiiv, go to each broadcast’s performance tab and note unsubscribes. Divide by your subscriber count at send time. Log it in a spreadsheet: date, subject line, unsubscribes, churn rate.

    In MailerLite, the campaign report shows unsubscribes per send. Export weekly and calculate rate yourself. The platform doesn’t auto-calculate churn percentage.

    In ConvertKit, open the broadcast, scroll to “Unsubscribed,” and divide by total sent. You’ll need to do this manually for each send.

    For transactional senders using Postmark, churn tracking is trickier—you’re not broadcasting, so attrition shows up as suppression list growth over time. Check your suppression report weekly and compare it to your active recipient count.

    Build a simple table: Send date | Subject | Subscribers at send | Unsubscribes | Churn % | Notes. The “Notes” column is where you log what was different: new content format, guest post, sales pitch, topic shift.

    What the numbers reveal

    Once you have four to six weeks of per-send churn data, patterns emerge.

    If churn spikes above 0.75% on a specific send, dig into the subject line and content. Was it off-topic? Too salesy? Did you mail twice in three days? Subscribers tolerate inconsistency poorly.

    If churn is flat but elevated—say, 0.6% every week—you have an acquisition problem, not a content problem. You’re attracting the wrong people, or your welcome sequence isn’t setting expectations. Check where new subscribers come from. Freebie-seekers and giveaway entrants churn fast.

    If churn is erratic—0.2% one week, 1.1% the next, 0.3% after that—you don’t have a consistent content thesis. Readers don’t know what to expect, so they bail when surprised.

    The silent cost of churn isn’t just lost readers. It’s deliverability erosion. High unsubscribe rates signal to inbox providers that your mail isn’t wanted. That compounds: your open rate drops, engagement falls, and future sends land in promotions or spam. A 1% monthly churn rate costs you roughly 12% of your list annually, but the deliverability hit costs you another 5–10% in effective reach.

    When to act on churn data

    Don’t overreact to a single bad send. Churn happens. But if you see two consecutive sends above 0.75%, or a four-week average above 0.5%, change something.

    Common fixes: tighten your welcome sequence to filter out freebie-hunters. Segment your list and stop mailing unengaged subscribers every week. Audit your lead magnets—if you’re promising one thing and delivering another, churn starts at signup. Test a weekly digest format instead of multiple sends. Cut sponsor placements that feel jarring.

    Track churn for eight weeks after any change. If it drops, you found the lever. If it doesn’t, revert and test something else.

    Churn is the tax you pay for growth. But silent churn—churn you don’t measure until it’s too late—is the tax you pay for inattention.

    Want more operator-to-operator breakdowns like this? Subscribe to One Two Three Send for weekly deep dives on the tools, tactics, and trade-offs that matter when you’re running a content business solo.

    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.

  • Google Search Console filtered data exports cap at 1,000 rows

    Google Search Console filtered data exports cap at 1,000 rows

    Google Search Console filtered data exports cap at 1,000 rows
    Photo by Justin Morgan on Unsplash

    Google Search Console lets you filter queries, pages, countries, devices—then export the results as a CSV. What the interface doesn’t tell you: any export caps at 1,000 rows, even if your filtered view shows “12,483 rows available.”

    If you run a content site with more than a few dozen published pieces, you’ve likely hit this ceiling without realizing it. The export completes without error. The file opens fine. You just never see row 1,001.

    Where the cap appears

    The 1,000-row limit applies to:

    • Performance report exports (queries, pages, countries, devices, search appearance)
    • Links report exports (top linking sites, top linking text)
    • Any filtered view, whether you’ve applied one filter or ten

    It does not apply to the API—more on that below.

    The cap exists across date ranges. If you’re exporting six months of query data and 4,200 queries triggered impressions, you’ll get the top 1,000 by impressions, sorted descending. The rest disappear.

    Why it matters for solo operators

    Most online-business operators export Search Console data for:

    • Finding low-hanging SEO opportunities (pages ranking 8–20 that could move up)
    • Identifying keyword cannibalization (multiple URLs competing for the same query)
    • Auditing underperforming content (impressions without clicks)
    • Building editorial calendars around actual search demand

    If your site has more than 1,000 indexed pages—or if you publish frequently enough that 1,000 queries have triggered impressions in the last 90 days—you’re analyzing an incomplete dataset every time you export.

    The pages that fall outside the top 1,000 by impressions are often the ones worth investigating: older posts that still rank but underperform, or newly published pieces that haven’t accumulated enough impressions to crack the top of the list.

    Three ways to pull complete data

    1. Tighten your filters before exporting. Instead of exporting all queries, filter by page first. Export queries for one URL at a time. Each per-page export will stay well under 1,000 rows unless you’re running a major publication. Tedious, but it works without code.

    2. Use the Search Console API. Google’s Search Console API returns up to 25,000 rows per request. You can script this in Python (the google-api-python-client library is well-documented), or use a no-code tool like Supmetrics or Coupler.io to pull data into Google Sheets. Expect to spend 30–60 minutes on initial setup if you’re not familiar with API authentication, but once it’s running, you can automate weekly or monthly pulls.

    3. Use Google Sheets’ built-in Search Console connector. In Sheets, go to Data > Data connectors > Connect to Search Console (previously called “Search Console add-on”). It uses the API under the hood, so you bypass the 1,000-row cap. Free, no coding required. The interface is slower than a CSV export, and you’ll need to refresh manually, but for most solo operators, this is the sweet spot between effort and completeness.

    What gets cut when you don’t notice

    I pulled a recent 28-day Performance report for a 200-page content site. The browser interface showed 2,103 queries. The CSV export contained exactly 1,000.

    The missing 1,103 queries had:

    • 14,822 total impressions (roughly 11% of the site’s total for the period)
    • 127 clicks
    • An average position of 24.3

    Those are queries where the site ranks on page 2 or 3—exactly the ones worth targeting for on-page optimization or internal linking. The export silently excluded them.

    One non-obvious detail

    When you export from a filtered view, Search Console sorts by the primary metric column (usually impressions) before applying the 1,000-row cap. If you’ve toggled the Performance chart to sort by clicks or position, the export still sorts by impressions. The UI doesn’t update to reflect this. If you want the top 1,000 queries by clicks, you’ll need to export, then re-sort in your spreadsheet—or use the API and specify orderBy: 'clicks' in your request.

    If you’re running content acquisition strategies based on Search Console exports, audit your row counts. If you’re seeing exactly 1,000 rows in every export, you’re working with a sample, not the full picture.

    Want more tooling breakdowns like this? Subscribe to One Two Three Send—one operator-focused article every day, no fluff.

  • WordPress auto-save interval: how often drafts get written to disk

    WordPress auto-save interval: how often drafts get written to disk

    WordPress auto-save interval: how often drafts get written to disk
    Photo: Pmpeev via Wikimedia Commons (CC BY-SA 4.0)

    WordPress has been auto-saving your drafts every 60 seconds since version 2.6 shipped in 2008. Most operators never touch this setting. That’s fine—until you’re working on a long-form post, lose a paragraph to a browser crash, and realize the last save was two minutes old because you were editing in two tabs at once.

    The auto-save interval is hardcoded to 60 seconds in core, but it’s filterable. Here’s how the feature actually works, when the default causes problems, and how to adjust it without breaking revision history.

    How WordPress auto-save writes to the database

    WordPress triggers auto-save via JavaScript heartbeat. Every 60 seconds, the editor sends a POST request to wp-admin/admin-ajax.php with your current draft content. The server writes it as a revision with post status inherit and type revision.

    This happens in addition to manual saves. If you hit “Save Draft,” WordPress writes a full post revision. Auto-save revisions are lighter—they don’t trigger plugin hooks tied to save_post, and they’re pruned more aggressively when you hit the revision limit.

    The 60-second interval is controlled by the AUTOSAVE_INTERVAL constant. If you don’t define it in wp-config.php, WordPress defaults to 60. The heartbeat itself runs every 15 seconds for most admin screens, but auto-save only fires every 60.

    When the default interval breaks down

    Two scenarios make 60 seconds too slow:

    Long-form content with lots of inline edits. If you’re writing 2,000+ word posts and rewriting sections as you go, you can lose several paragraphs between auto-saves. Browser crashes, tab freezes, and accidental closes all mean you’re back to the last 60-second checkpoint.

    Multi-tab editing. Open the same post in two tabs and WordPress gets confused. Auto-save from tab A can overwrite content from tab B if you’re typing in both. The last heartbeat wins. WordPress shows a warning banner when it detects concurrent editing, but if you’re switching between tabs quickly—fact-checking in one, writing in the other—you can trigger a race condition. Shortening the interval makes the conflict surface faster, which is actually useful.

    The opposite problem—too-frequent saves—can happen if you set the interval below 30 seconds. Every auto-save writes a row to wp_posts. On shared hosting with strict query-per-hour limits, aggressive auto-save during a long editing session can eat your quota. I’ve seen this on budget plans that cap at 10,000 queries per hour. Two hours of editing at 15-second intervals is 480 saves. Add in plugin queries and you’re close to the limit.

    How to override the interval

    Add this to wp-config.php before the “stop editing” line:

    define('AUTOSAVE_INTERVAL', 30);

    That changes the interval to 30 seconds. You can go as low as 10, but I don’t recommend it unless you’re on managed hosting with no query caps. WordPress doesn’t enforce a floor—you could set it to 5—but the heartbeat API starts to lag if you hammer admin-ajax too hard.

    If you’re using the block editor (Gutenberg), auto-save behaves slightly differently. The editor keeps an in-browser copy of your content in IndexedDB and syncs it to the server every 60 seconds. The constant still controls the server interval, but the browser cache means you’re less likely to lose content entirely. The trade-off: if IndexedDB gets cleared (some privacy extensions do this), you lose anything not synced to the server.

    One non-obvious tip: if you’re working on a staging site or local dev environment and don’t want auto-save cluttering your revision history, set the interval to something absurdly high—300 or 600 seconds. WordPress will still save, but only every five or ten minutes. Alternatively, disable revisions entirely with define('WP_POST_REVISIONS', false);, but that also kills manual revision history.

    What happens when auto-save conflicts with plugins

    Some page builders—Elementor, Divi, Oxygen—bypass WordPress auto-save entirely and use their own save mechanisms. If you set AUTOSAVE_INTERVAL and nothing changes, check whether your editor is hooking into the native system. Elementor, for instance, saves to post meta on every change and only writes to post_content when you hit “Update.” The constant won’t affect that flow.

    Collaboration plugins like EditFlow and PublishPress can also interfere. They add their own revision logic and sometimes double-save—once for WordPress, once for their audit log. If you’re seeing duplicate revisions or slow saves, try disabling those plugins temporarily and testing the interval change in isolation.

    If you’re running a membership site or gated content setup, make sure auto-save respects your access control. Some plugins (especially older ones) don’t check capabilities on the admin-ajax endpoint, which means a non-privileged user could theoretically trigger auto-save on someone else’s draft. Most modern security plugins catch this, but it’s worth auditing if you have custom roles.

    When to leave it alone

    If you’re writing short posts (under 500 words), publishing quickly, and rarely editing in multiple tabs, the default 60-second interval is fine. The performance cost of changing it is near zero on modern hosting, but there’s no upside if you’re not hitting the edge cases.

    For solo operators publishing a weekly newsletter and drafting in WordPress, the bigger risk is usually forgetting to hit publish, not losing content mid-draft. Auto-save won’t help with that.

    Want more WordPress infrastructure breakdowns? Subscribe to One Two Three Send—we cover hosting, performance, and workflow mechanics for online operators every week.

  • LinkedIn carousel PDFs get auto-compressed—here’s the resolution floor

    LinkedIn carousel PDFs get auto-compressed—here’s the resolution floor

    LinkedIn carousel PDFs get auto-compressed—here's the resolution floor
    Photo by Souvik Banerjee on Unsplash

    If you’ve uploaded a carousel PDF to LinkedIn and watched the text turn blurry or the charts pixelate, you’ve hit the platform’s automatic compression pipeline. LinkedIn doesn’t publish the exact spec, but testing across dozens of uploads reveals a consistent pattern: PDFs get resampled to a maximum width of 1080 pixels per slide, regardless of your original export resolution.

    That means exporting at 4K or even 2K is a waste of file size—and often makes compression worse, because LinkedIn’s algorithm has to work harder to downsample a massive file into its fixed output window.

    What LinkedIn’s compression pipeline actually does

    When you upload a multi-page PDF as a carousel post, LinkedIn converts each page into a raster image. The platform applies lossy JPEG compression at around 80–85% quality, then serves the result at a fixed width of 1080 pixels. Height scales proportionally, but the horizontal cap is hard.

    If your original PDF contains vector text or high-res images exported at 300 DPI and 3000 pixels wide, LinkedIn downsamples it. If you export at exactly 1080 pixels wide, LinkedIn still compresses it—but the quality loss is minimal, because there’s no resampling step.

    Text suffers most. Small sans-serif fonts at 10–12pt become fuzzy after downsample and compression. Charts with thin grid lines lose definition. Gradients band visibly.

    The export settings that survive compression

    After testing Canva, Figma, Adobe Illustrator, and Keynote exports, here’s what works:

    • Canvas size: 1080 × 1080 pixels for square carousels, or 1080 × 1350 pixels for portrait (4:5 ratio). LinkedIn supports both, but square is more common.
    • Export resolution: 72–150 DPI. Anything higher gets downsampled anyway. Save the file size.
    • Font size floor: 18pt minimum for body text, 24pt for headlines. Smaller than that and compression blur makes it hard to read on mobile.
    • Line weight: 2px minimum for borders, dividers, and chart axes. 1px lines disappear after compression.
    • Color mode: RGB, not CMYK. LinkedIn’s pipeline expects screen color space.

    If you’re exporting from Canva, choose “PDF Standard” rather than “PDF Print”—the print preset defaults to CMYK and 300 DPI, both of which get mangled. Figma users should export as PDF at 1× scale, not 2× or 3×.

    When compression visibly degrades your slides

    Three scenarios cause the worst quality loss:

    Screenshots of text. If you embed a screenshot of a tweet, email, or dashboard inside your carousel slide, and that screenshot contains small text, compression will blur it twice—once when you captured it, once when LinkedIn resamples the PDF. Better to recreate the layout with live text in your design tool.

    Gradients and soft shadows. Subtle gradients band into visible stripes after JPEG compression. Use solid fills or high-contrast gradients (light to dark, not light to slightly-less-light).

    Busy backgrounds. Textured or photographic backgrounds behind text create compression artifacts that make the text harder to read. Stick to solid colors or very simple geometric patterns.

    File size and upload speed

    LinkedIn’s upload interface accepts PDFs up to 100 MB, but anything over 5 MB takes noticeably longer to process—sometimes 30–60 seconds before the post preview renders. A ten-slide carousel exported at 1080px width and 72 DPI typically lands between 800 KB and 2 MB, which uploads and processes in under ten seconds.

    If your file is larger than 3 MB, check your export settings. You’re probably rendering at a higher resolution than LinkedIn can use, or embedding uncompressed images inside the PDF.

    Most design tools let you compress images before export. In Canva, this happens automatically when you choose “PDF Standard.” In Figma, use the “Flatten” option before exporting. In Illustrator, go to File → Save As → PDF, then set “Compression” to JPEG, Medium quality.

    One more thing: LinkedIn’s mobile crop

    Even if you export at 1080 × 1080, LinkedIn’s mobile app often crops the top and bottom edges of each slide in the feed preview. Users have to tap through to see the full slide. That means critical text—headlines, CTAs, key data points—should sit in the center 80% of the canvas, not near the edges.

    Test your carousel by uploading it as a draft post, then viewing it on your phone before publishing. If your headline gets cut off in the preview, move it down.

    Want more tool-specific breakdowns like this? Subscribe to One Two Three Send—one operator-to-operator article every day, no fluff.

  • Patreon video hosting compresses uploads—here’s the bitrate cap

    If you’re running a membership site and uploading video directly to Patreon, you’re not serving the file you uploaded. Patreon re-encodes every video through its own compression pipeline, and the quality ceiling is lower than most creators realize.

    This isn’t mentioned in their help docs with any specificity. But if you’re producing tutorial content, screen recordings, or any video where detail matters, you’ll notice: edges blur, text becomes harder to read, and fine detail disappears.

    Here’s what’s actually happening, and what your alternatives are.

    The re-encoding pipeline

    Patreon accepts uploads up to 5 GB. But once the file hits their servers, it’s re-encoded to a maximum bitrate of approximately 3 Mbps for 1080p video. For 4K, the cap sits around 8 Mbps.

    For context, a locally rendered 1080p screen recording at 10 Mbps—common for something like a Camtasia or ScreenFlow export—will be crushed down by 70%. That’s where readability suffers. Code editors, spreadsheets, browser UI, anything with small text or fine lines gets softened.

    The audio track is re-encoded to 128 kbps AAC. That’s acceptable for most spoken-word content, but if you’re including music or high-fidelity audio, you’ll hear compression artifacts.

    Patreon also generates multiple resolution variants (1080p, 720p, 480p, 360p) regardless of what you upload. The adaptive player selects based on the viewer’s bandwidth. That’s good for delivery reliability, but you lose control over which version gets shown.

    When it matters

    If your content is talking-head video, interviews, or anything where the subject is well-lit and centered, Patreon’s compression is fine. The platform is optimized for that use case.

    But if you’re teaching software, showing design work, presenting data visualizations, or doing any screen-based tutorial content, the quality loss is immediately visible. Text at 12–14 pt becomes fuzzy. UI elements lose definition. Viewers squint.

    This also applies to animation or motion graphics with flat colors and hard edges. Compression algorithms handle gradients and organic textures better than sharp contrasts.

    What you can do instead

    The simplest workaround: host video elsewhere and embed or link from Patreon posts.

    Vimeo is the most common choice. A Vimeo Plus account ($12/month as of mid-2026) gives you 5 TB of annual upload capacity and lets you control compression settings. You can set a minimum bitrate, disable lower-resolution variants, and embed with privacy controls that restrict playback to specific domains or require a password.

    Upload your video to Vimeo, set the privacy to “Hide from Vimeo,” generate the embed code, and paste it into your Patreon post. Patreon allows iframe embeds in posts for patrons at any tier.

    Bunny.net Stream is a cheaper option if you’re comfortable with a little more setup. Pricing is usage-based: $5 per TB of storage and $1 per TB of bandwidth. For most solo operators, that’s well under $10/month. You upload via API or dashboard, and Bunny generates an embed player. You can set encoding profiles and control bitrate ceilings yourself.

    The trade-off: Bunny doesn’t have the same content discovery or social features Vimeo offers. But if you’re only using it as a private CDN for your membership, that doesn’t matter.

    Self-hosting on WordPress with a CDN is technically possible, but unless you’re already paying for significant bandwidth and storage, it’s rarely worth it. A 500 MB video file served to 200 members is 100 GB of bandwidth. Most shared hosting plans will throttle or surcharge you. If you’re on a VPS or dedicated plan and already using a service like BunnyCDN or Cloudflare Stream for delivery, it works—but for most operators, offloading to a dedicated video host is simpler.

    One more thing: downloadable video

    If your members expect to download video files—common for course content or archival access—Patreon does let you attach files to posts, including .mp4 files. Those are not re-encoded. The file you upload is the file they download.

    But downloads don’t get streamed previews, and most members won’t bother unless you explicitly frame it as an offline-access perk. Streaming is still the default expectation.

    If you’re running a course or tutorial membership and video quality matters, don’t assume Patreon’s hosting will preserve what you produced. Check a test upload at full screen on a typical laptop display. If text is hard to read, route the video through Vimeo or Bunny and embed it instead.

    Got a technical question about your online-business stack? Reply to this email—we cover one reader question every Sunday.