SEO Workflow: The Weekly Loop When You Are the Team

Search the United States results for "seo workflow" and the first organic position is a Reddit thread. Position 3 is the homepage of a free tool. Position 5 is a project management vendor's blog, position 8 is an agency post that ends by inviting you to bring in the pros, and position 10 is a trade publication.
Measured traffic on those pages: 352, 214, 72, 69 and 84 visits a month. The link floor is just as low. The agency post at position 8 sits on a single backlink. The Reddit thread at position 2 also has one.
So the query is wide open, and every page answering it was written for someone who has a team to coordinate. None of them was written for the person who ships the product on Tuesday and writes the blog post on Wednesday.
That person does not need a Kanban board. They need a loop that makes decisions for them, because the decisions are what consume the week: which keyword, whether the page is worth writing at all, when to stop editing, and what to do when a published article goes nowhere.
This article is that loop. Five stages, the rule that ends each one, and the commands that prove the stage actually happened.
What a one-person SEO workflow has to decide, not do
A task list cannot fail. A decision rule can, and that is the point of writing it down.
Most published SEO workflows are lists of activities: research keywords, write a brief, optimize the page, build links, report. Every item is true and none of them tells you when to stop or what to do with the answer. The two ranking guides above both offer seven numbered steps and not one threshold.
A workflow that works solo decides four things, in this order:
- Which query gets this week's article. One query, chosen by a rule you can apply in ten minutes.
- Whether that query is worth a page at all. Most are not, and finding out costs minutes instead of a weekend.
- Whether the page is technically done. Not "does it look good" but "does the canonical, the sitemap entry and the structured data exist", which is checkable with curl.
- What to do with the article in ninety days. Keep, rewrite the title, merge it, or remove it.
Everything else is production. Production is the easy part when you can write about your own product. The failure mode of a solo blog is not slow writing, it is writing the wrong page, discovering nothing happened, and quietly stopping.
Automation helps with exactly the parts where the machine can check its own output, which is the subject of what to script and what to do by hand. The four decisions above are not those parts.
The loop, in five stages and roughly four hours
Here is the whole thing on one screen. The stop rule matters more than the duration: a stage that has no end condition is where a week disappears.
| Stage | Output | Stop rule | Rough time |
|---|---|---|---|
| 1. Pick the query | One primary keyword, written down with its numbers | Volume and difficulty pass, parent topic is itself | 20 min |
| 2. Read the results | A go or no-go, with the reason | Top ten shows people doing the work, not buying it | 30 min |
| 3. Write and publish | One page, live, with its plumbing attached | Canonical, sitemap entry and JSON-LD all return from curl | 2 to 3 h |
| 4. Prove it is indexable | A crawled, indexed URL | URL Inspection shows the page indexed with the canonical you chose | 10 min |
| 5. Decide from the numbers | One verdict per older article | Every page with 50+ impressions has a verdict | 30 min/week |
One article a week, not five in a burst. Not because volume is bad, but because stage 5 needs something to read. A batch of twenty pages published in one weekend gives you twenty unmeasured bets and no feedback for a quarter. Pacing is covered in more detail in how long SEO takes to work.
Four hours is the steady state, after the first run. The first run takes longer because stage 3 includes plumbing you only build once.
Stage 1: pick the query with a rule, not a hunch
The rule has four conditions. All four are cheap, and three of them are free.
Volume at or above 50 a month, difficulty at or below 20. These are the floors we use on our own queue. Below 50, a first-page position produces a handful of visits. Above difficulty 20, a young domain is writing for an audience of nobody.
The parent topic has to be the query itself. This is the condition most people skip and the one that saves the most wasted writing. If the keyword tool reports a different parent topic, the page ranking first for your query earns its traffic from something else, which means the slot is held by a page about another subject.
A worked example from this week. Our queue carried "perplexity seo" at 459 searches a month and difficulty 4, which passes both floors comfortably. Its parent topic came back as "computer seo", so the page winning that query is known for a different topic entirely. We left it in the queue unwritten and picked "seo workflow", whose parent topic is itself.
Cost per click as an intent tell. This one is nearly free and it is the fastest sorter we have found. A query where advertisers pay seven to thirteen dollars a click is a query where someone is buying a service. "Seo workflow" prices at $3.50, and the queries we rejected in the same batch for being provider shopping sat at $7.00 and $8.00.
For the free version of the same instinct, read what Google's own autocomplete attaches to your seed:
curl -s "https://suggestqueries.google.com/complete/search?client=firefox&hl=en&gl=us&q=seo+workflow" | jq '.[1]'
Run today, that returns:
["seo workflows","seo workflow automation","seo workflow management",
"seo workflow n8n","seo workflow process","seo workflow template",
"seo workflow diagram","seo workflow meaning","chatgpt seo workflows",
"seo content workflow"]
Every one of those is a doing query. Not one is "seo workflow agency" or "seo workflow services". Compare that with a seed like "shopify seo", where the suggestions fill up with experts and companies, and you have the audience check before you have paid for anything.
The second free source is your own data. Any page with impressions and no clicks is already telling you which queries Google thinks you answer:
ACCESS_TOKEN=$(gcloud auth print-access-token)
curl -s -X POST \
"https://www.googleapis.com/webmasters/v3/sites/sc-domain:example.com/searchAnalytics/query" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"startDate":"2026-09-01","endDate":"2026-09-30",
"dimensions":["query"],"rowLimit":1000}' | jq '.rows[:20]'
Two caveats worth knowing before you build reporting on that endpoint. rowLimit accepts 1 to 25,000 and defaults to 1,000. And Google states plainly that the API "is bounded by internal limitations of Search Console and does not guarantee to return all data rows but rather top ones", so treat the output as a sample of your demand, not a census.
Write the chosen keyword down with its four numbers. A keyword you cannot restate with its volume, difficulty, parent and price is a keyword you picked on vibes.
Stage 2: read the results before you write a word
Thirty minutes here is the highest-value half hour in the loop, and it answers one question: are the people on this page doing the work, or hiring someone to do it?
Four things to read, in order.
What kind of pages rank. Service pages and vendor landing pages in the top three mean the click is shopping for a provider. For "seo workflow" the top ten contains zero service pages: two Reddit threads, one tool homepage, two tutorials and a trade publication article. That is a SERP of people doing it themselves.
What each ranking page is actually known for. Positions 2, 3, 5 and 9 all report "seo workflow" as their top keyword, which confirms the results are about the query rather than catching it in passing. When a page's top keyword belongs to another topic, the results are not about what you think they are.
The link floor at positions 8 to 10. This is the entry price, and it is far more honest than a difficulty score. Here, position 8 is a domain rating 51 site with one backlink, and position 9 is a Reddit thread with 38. A blog with no link profile can enter this page. By contrast, a top ten where nothing sits below a few hundred backlinks is a wall, whatever the difficulty number says.
Whether an AI Overview sits on top. This one does, with seven cited links, four of which are YouTube videos and Reddit. That is a real zero-click risk and it belongs in the decision rather than in a footnote: a share of these searchers will read the summary and never click. Google's own position is that there are "no additional technical requirements" to be cited there and that "you don't need to create new machine readable files, AI text files, or markup to appear in these features". Being indexed and snippet-eligible is the requirement. Showing up in assistant answers more broadly is a different exercise, covered in answer engine optimization and LLM SEO.
The no-go side of this stage is the part worth defending. If the results are a wall of agencies selling the service, skip the query no matter how good the volume looks. A page that ranks for the wrong reader produces traffic and no customers, which is the exact failure we describe in is SEO worth it.
While you are here, grab the questions Google shows on the page. The four on this one are "Is SEO dead now with AI?", "What are the 5 best SEO tools?", "Can ChatGPT do SEO?" and "What is the 80/20 rule in SEO?". They become the FAQ at the bottom of your article, which is where the long-tail variants live.
Stage 3: publish with the plumbing attached
The writing is yours. The plumbing is the same every time, which is why it belongs in code rather than in a checklist you re-read.
On Next.js with the App Router, three things ship with the page. This repo runs 16.2.12, and the shapes below are the ones in the current docs.
The canonical and the metadata, in the route itself:
// app/blog/[slug]/page.tsx
import type { Metadata } from 'next'
export async function generateMetadata(
{ params }: { params: Promise<{ slug: string }> },
): Promise<Metadata> {
const { slug } = await params
const post = await getPost(slug)
return {
title: post.title,
description: post.description,
alternates: { canonical: `https://example.com/blog/${slug}` },
openGraph: { type: 'article', publishedTime: post.date },
}
}
The sitemap entry, generated rather than maintained:
// app/sitemap.ts
import type { MetadataRoute } from 'next'
export default function sitemap(): MetadataRoute.Sitemap {
const posts = getAllPosts()
return [
{ url: 'https://example.com', lastModified: new Date() },
...posts.map((post) => ({
url: `https://example.com/blog/${post.slug}`,
lastModified: post.updatedAt ?? post.date,
})),
]
}
Two facts about that file that save arguments. Google "disregards <priority> and <changefreq> values entirely", so the fields the type system offers you are decoration. And <lastmod> is used only "if it's consistently and verifiably (for example by comparing to the last modification of the page) accurate", which means stamping every page with today's build date trains Google to ignore the field. Our own sitemap still carries priority and changeFrequency, which is honest decoration and not a ranking lever.
If a single sitemap ever gets large, the limit is "50MB (uncompressed) or 50,000 URLs" per file, and Next.js splits with generateSitemaps. Since version 16 the id argument arrives as a promise you await, so older snippets will not type-check.
The structured data, emitted from the same post object:
const jsonLd = {
'@context': 'https://schema.org',
'@type': 'BlogPosting',
headline: post.title,
datePublished: post.date, // ISO 8601, with timezone
dateModified: post.updatedAt ?? post.date,
author: { '@type': 'Person', name: post.author, url: 'https://example.com/about' },
}
return (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
/>
)
Google's Article documentation is blunter than most advice about it: "There are no required properties; instead, add the properties that apply to your content", and Article, NewsArticle and BlogPosting are the three accepted types. Dates go in ISO 8601 and Google recommends including timezone information, defaulting to Googlebot's timezone otherwise.
The sentence to keep in mind before spending an evening on markup: "Google does not guarantee that features that consume structured data will show up in search results." Correct markup makes a rich result possible, not certain.
Do not bump dateModified because you fixed a typo. The field is a claim about the content, and a blog where every page changed last night is a blog that has told Google its dates mean nothing.
Stage 4: prove the page is indexable instead of hoping
Ten minutes, three checks, all of them the kind of thing you can run from your terminal while the build deploys.
Does the live page carry what you think it carries?
URL=https://example.com/blog/seo-workflow
curl -s -o /dev/null -w "%{http_code}\n" "$URL"
curl -s "$URL" | grep -Eo '<link rel="canonical"[^>]*>|"@type":"BlogPosting"'
curl -s https://example.com/sitemap.xml | grep -c "seo-workflow"
Three lines, three failure modes caught: a page that returns 404 or a redirect, a canonical pointing at the wrong URL, and a page missing from the sitemap because the build cached the old list.
Then ask Search Console, and read the answer carefully. The URL Inspection report shows the indexed version, not the current one: "This is not a live test. The results shown are from most recently indexed version of a page." The live test is a separate button on the same screen. Mixing them up is how people conclude a fix did not work an hour after shipping it.
Request indexing once, then let it be. Google notes a daily limit on index requests, says submitting a sitemap is the better path for multiple pages, and warns that "submitting a request does not guarantee that the page will appear in the Google Index". Their published expectation is that indexing "typically takes only a day or so, but can take much longer in some cases".
Two things not to bother with. The site: operator is not a coverage report: "it's not guaranteed" that an indexed URL shows up for it, and it "doesn't necessarily return all the URLs that are indexed under the prefix specified in the query". And the Indexing API does not apply to a blog, since it only supports JobPosting structured data and BroadcastEvent embedded in a VideoObject.
When a page stays missing after a week, the diagnosis has branches rather than a single cause, and why a website is not showing up on Google walks each status string from the Page Indexing report.
Stage 5: decide what the numbers mean
Half an hour a week, and it is the stage people skip. Skipping it turns a blog into a pile of pages nobody has read, including their author.
Pull impressions, clicks and position per page, then apply three rules.
Impressions above roughly 50 with zero clicks, position inside the top 15. The page is being shown and not chosen. Rewrite the title and description, change nothing else, and wait two weeks. Our own property is a live example of this rule: over the last 28 days, /blog/seo-keywords-for-photographers collected 58 impressions and zero clicks, and /blog/llm-brand-visibility 51 impressions and zero clicks, while the only page earning clicks was the homepage on our brand name, at 42 impressions and five clicks.
Position between 20 and 50 with impressions. Google has decided the page is on topic and not the answer. That is a content verdict, not a title verdict, and usually it means the stage 2 read was optimistic.
No impressions at all after a few weeks. That is a stage 4 problem, not a ranking problem. Go back to indexability before touching the text.
Three constraints from Google's own guidance keep this stage from becoming thrashing. Ranking changes take time: "some changes can take effect in a few days, while others could take several months". Noise is normal: "small fluctuations in position can happen at any time (including moving back up in position, without you needing to do anything)". And Google explicitly recommends "avoiding making radical changes if your page is already performing well".
One reporting detail that trips people up: traffic from AI Overviews and AI Mode is "included in the overall search traffic in Search Console" under the Web search type, so there is no separate bucket to find. If your clicks dropped while impressions held, that is a CTR story, and the AI summary above the results is one of the candidate explanations.
No one can guarantee a position or a date for any of this. What the loop guarantees is that you find out, in weeks rather than never, which of your pages is working.
What to automate, and what breaks when you do
The dividing line is whether the machine can verify its own output.
Safe to script, because correctness is checkable:
- Sitemap generation, canonical tags and JSON-LD, all derived from the post itself.
- The three curl checks in stage 4, run on every deploy.
- The Search Console pull in stage 5, into a weekly file.
- Internal link checks: every
/blog/xlink in a new article resolving to a file that exists. - Core Web Vitals monitoring against the published thresholds: LCP within 2.5 seconds, INP at 200 milliseconds or less, CLS at 0.1 or less, each assessed at "the 75th percentile of page loads, segmented across mobile and desktop devices".
Not safe to script, because nothing in the data says whether the answer is right:
- Choosing the query. Volume and difficulty are inputs to a decision, not the decision.
- Reading the results for audience. Whether the people ranking are selling what you sell lives in your judgment.
- Deciding to publish. A draft that is accurate but says nothing is the one thing a volume tool cannot catch.
A generator with no gate in front of it produces exactly what the top of this SERP looks like: pages that cover the subject and help nobody. AI SEO agents are useful in proportion to the checks wrapped around them, and the checks are the product.
When the loop stalls
Three failure modes, with the move for each.
The query list is empty. Harvest before you write: autocomplete on five seeds, your own Search Console queries, and the questions shown on the SERPs you already read. The point is a list of twenty candidates, which keeps stage 1 from becoming a two-hour wander.
Nothing passes the gates. Widen the seeds, do not lower the bar. The one threshold that should never move is the overlap rule: if an existing page of yours already targets the query, do not publish a second one. Two of your own pages competing is worse than publishing nothing, and the fix later is a merge or a redirect. The decision procedure for that is in the SEO content audit.
A page is flat after ninety days. Give it a verdict rather than a shrug. Keep, rewrite the title, merge into a stronger page, or remove it. The audit article covers each branch, and architecture questions like where the blog lives in the first place are in subdomain versus subfolder.
The loop survives a bad week. What kills a solo SEO program is not a slow month, it is twenty unmeasured pages and no rule for what to do next. Writing less and deciding more is the trade, and how to get traffic to your website shows what the measurement looks like once a few pages are live.
FAQ
What is an SEO workflow process?
It is the repeatable sequence that takes a query from candidate to measured page: pick the keyword, read the results, write and publish with the technical parts attached, confirm the page is indexed, then read the numbers and act. What makes it a process rather than a list is that each step has a stop rule, so you know when it is finished and what the next step receives.
How long should a weekly SEO workflow take?
About four hours a week in the steady state for one article, with roughly 20 minutes on the keyword, 30 on the search results, two to three hours writing and publishing, 10 minutes confirming indexability and 30 minutes reviewing older pages. The first cycle takes longer because the sitemap, canonical and structured data are built once and then reused.
Is SEO dead now with AI?
Search behavior is changing and the mechanics are not dead. Google states that pages shown in AI Overviews and AI Mode must be "indexed and eligible to be shown in Google Search with a snippet" and that there are "no additional technical requirements", so the eligibility work is the same work. What has changed is click-through: a summary above the results absorbs some clicks, so a query whose answer fits in two sentences is worth less than it used to be.
Can ChatGPT do SEO?
It can draft and edit text, and it cannot do the two parts that decide whether a page is worth publishing. It has no access to live search results, so it cannot tell you who ranks for your query or whether those pages target your buyer. Used inside the loop above, as the writing stage with the keyword and the SERP read already done by you, it saves hours. Used as the whole workflow, it produces the pages this article opened by measuring.
What is the 80/20 rule in SEO?
The common version says a small share of pages produces most of the traffic, which usually holds on a blog of any size. The practical consequence for a solo operator is in stage 5: once two or three pages are carrying the property, the next hour is better spent improving those than adding a tenth page. Our own property is currently an extreme version, with one page taking all the clicks.
Do I need an SEO workflow template or a diagram?
Only if it carries the thresholds. A diagram of boxes labeled research, write, optimize and report is the thing every ranking page for this query already offers, and it does not change a single decision. The useful artifact is five lines of text with the numbers in them: your volume floor, your difficulty ceiling, the parent topic test, the impressions threshold that triggers a title rewrite, and the day count after which a flat page gets a verdict.
Get cited by ChatGPT. Rank on Google.
You found this article through search. That is the whole product.
- One researched article a day
- Published on your own domain
- Keywords checked against live results
Get cited by ChatGPT. Rank on Google.
You found this article through search. That is the whole product.
- One researched article a day
- Published on your own domain
- Keywords checked against live results
