SEO URL structure best practice, minus the folklore
Search for URL structure advice and you get a list of rules delivered with total confidence and no evidence: hyphens beat underscores, keep it under some number of characters, get your keyword in the slug. Some of that is in Google's own documentation. Some of it has never been published by anyone who measured it. This page separates the two, and says plainly which of them Docket checks — because the answer is fewer than you would guess.
Docket registers one check here, index.url_hygiene, under the title
"URL structure", in the crawlability and indexing lane. It emits up to 5 findings.
Here they are, with the condition that fires each, exactly as the code has it.
The five findings
A session ID in the query string
Finding index.session_ids, at HIGH — the most severe thing this check can say.
It fires on a URL whose query string matches sid=, sessionid=,
phpsessid= or jsessionid=, case-insensitively. The detail text is
blunt about why: a session ID makes a new, unique URL for every visit, which is an effectively
infinite duplicate-content space. The fix is to move session state into cookies and strip the
parameter from crawlable URLs.
This one has a source, and it is the only finding in the check that Google's own documentation addresses head-on. Read on 16 September 2026, Google's URL structure documentation lists session IDs among the irrelevant parameters that inflate a site's URL count, and says: "Wherever possible, avoid the use of session IDs in URLs and consider using cookies instead."
Uppercase letters in the path
Finding index.url_uppercase, at LOW. Any uppercase letter anywhere in the path
fires it. Not the host, which is case-insensitive by definition; not the query string. Just the
path. The stated reason is that a path is case-sensitive on most servers, so two casings of the
same page can both be indexed, and the fix is to standardise on lowercase and redirect the
mixed-case versions permanently.
Sourced, again on 16 September 2026: "Like any other HTTP client following IETF STD 66, Google
Search's URL handling is case sensitive (for example, Google treats both /APPLE
and /apple as distinct URLs with their own content)." The same passage says what
to do if your server does not care about case — "convert all text to the same case so it's
easier for Google to determine that URLs reference the same page."
Encoded spaces — and this title is wider than its rule
Finding index.url_spaces, at LOW. It fires when the path contains
%20 or a literal +. The reasoning given is practical
rather than algorithmic: spaces in URLs are ugly when shared, break in plain-text contexts and
get mis-copied. The fix is to use hyphens between words.
The second trigger is looser than the finding's name. A + means a space only
inside an application/x-www-form-urlencoded payload, which is a query-string
format — the WHATWG URL Standard spells the substitution out in its parsing steps: "Replace any 0x2B (+) in
name and value with 0x20 (SP)", where name and value are the halves of a query pair. In a path
segment a plus is just a plus. So a page published at a path containing one gets reported as
carrying an encoded space when it carries no space at all. Worth knowing before you go and
rename anything.
A long URL
Finding index.url_long, at NOTICE — the lowest severity Docket reports a
defect at, and correctly so. It fires when the URL is longer than 115 characters. The detail text says
long URLs get truncated in search results and shared links; the fix says to shorten slugs to
the two or three words that describe the page.
Two honest caveats. The measurement is taken over the entire absolute URL — scheme, host and all — while the advice talks about slugs, so a long hostname spends part of a budget you cannot edit by renaming a page. And the threshold itself has no outside source. It is a house number, chosen by us. Read in full on 16 September 2026, Google's URL structure documentation states no character limit for URLs anywhere on the page. That is why this finding is a notice and not an error, and why nothing here tells you that a URL over that length will rank worse. Nobody knows that.
Lots of parameterised URLs
Finding index.url_params, at MEDIUM, and the only one of the five with a
site-level threshold rather than a per-URL one. A URL counts toward it when its query string
contains at least 2 ampersands, which means 3 or more key-value
pairs — two parameters never counts. The finding is then reported only if the number of such
URLs exceeds both a floor of 3 and 25 per cent of the indexable
pages in the crawl, whichever is larger. A handful of filtered URLs on a big site stays quiet.
A site that is mostly filter combinations does not.
The remedy attached to it was rewritten after a sweep through every fix text in the product asking one question of each: what happens to a reader who does exactly this? The old sentence asked for a canonical on parameterised URLs and a robots.txt disallow on the same patterns. Each is defensible alone. Together they defeat each other, because a URL Googlebot cannot fetch is a canonical it cannot read, and the URL can still be indexed with nothing behind it. The advice now gives them as alternatives and says which case each suits: canonicalise and stay crawlable for parameter spaces you want consolidated; disallow, and do not bother with a canonical, for spaces you never want crawled at all.
What this page refuses to tell you
That hyphens beat underscores for ranking. Google's URL structure documentation does recommend hyphens
— "we recommend using hyphens (-) instead of underscores (_) to
separate words in your URLs, as it helps users and search engines better identify concepts in
the URL" — and gives a reason that is about legibility and convention, not about a scoring
difference: underscores are already used to join words into single names in programming
languages. No effect size is published. And Docket does not check for underscores at
all. No finding in this check looks at them. A page that told you Docket enforced
Google's hyphen recommendation would be describing software that does not exist.
That a keyword in the URL is worth restructuring for. The closest thing to a source is the recommendation to "use readable words rather than long ID numbers in your URLs", which is an argument about human comprehension and sits under a heading about descriptive URLs. No weight, no measurement, no ranking claim. Docket checks nothing of the kind and will never tell you a slug is missing a keyword.
That there is an ideal URL length. Covered above: our own threshold is a house number and is labelled as one, and Google publishes none.
Being precise here cuts our own side too, which is the point of saying it out loud. The uppercase finding's premise — that paths are case-sensitive on most servers — is stated as a general fact by the check and is not measured by it per site; Docket does not probe your server to find out whether it folds case. Treat that finding as "these URLs could be a duplicate pair" rather than "these URLs are one".
What the crawl actually saw
All five findings are computed over the crawl's indexable pages: fetched, HTML, an OK status,
not carrying noindex. That has consequences worth holding on to. A URL the crawl
never reached is in none of these lists. A URL your sitemap declares but nothing links to may or
may not be in them, depending on how far the crawl got. And a parameterised URL that you have
already excluded with noindex is correctly invisible here, because it is not a page
competing for indexing.
So the counts are a floor, not a census — the shape of the problem on the pages Docket read, which on a large site is a sample. If a parameter space is the thing you are worried about, the number that matters is not in the finding; it is in whether the crawl kept discovering new combinations until it ran out of budget.
What to do with the list
In severity order, which is also roughly the order of how much a fix buys you. Session IDs first — that is a duplicate-content generator and the only item here Google's documentation explicitly asks you to remove. Then the parameter finding, if it fired, taking the canonical route or the robots.txt route but not both. Then casing, which is a server rule plus redirects rather than a URL-by-URL job. The encoded-space and long-URL findings are cosmetic; they are a notice and a low for a reason, and renaming live URLs to satisfy them costs you redirects you did not need.
The thread running through most of this is which URL gets indexed when several serve the same thing, which is a bigger subject than any one check. What a canonical tag actually does covers the declaration you make about that directly, including how often it gets overridden; index coverage covers reading the outcome. And if the fix you land on is a redirect, redirect loops, chains and internal links pointing at redirects is the shape to avoid creating on the way.
Common questions
Does Docket check whether my URLs use hyphens instead of underscores?
No. Google's URL structure documentation does recommend hyphens over underscores, and gives a legibility reason rather than a ranking one, but no finding in Docket's URL structure check looks at underscores. The check reports session IDs, uppercase letters in the path, encoded spaces, URLs past a length threshold, and a site that is mostly parameterised URLs.
What is the ideal URL length for SEO?
There is no published figure, and this page does not invent one. Google's URL structure documentation states no character limit anywhere. Docket does have a length threshold, it is a number we chose rather than one we measured, and the finding it produces is a notice rather than an error for exactly that reason.
Do keywords in the URL help rankings?
No source we can cite says so with a measurement attached. Google's guidance is to use readable words rather than long ID numbers, which is an argument about people understanding the URL. Docket never reports a URL for lacking a keyword, and restructuring live URLs on that theory costs you redirects for no known gain.
Why is a URL flagged for encoded spaces when it has no space in it?
The rule fires on a literal plus sign in the path as well as on a percent-encoded space, and a plus only means a space inside a query string, where the form-urlencoded format defines that substitution. In a path segment a plus is just a character. The finding is accurate about what it matched and wider than its title suggests, so check the URL before renaming anything.
My site uses query parameters everywhere and Docket said nothing. Why?
That finding is the only one in the check with a site-level threshold. A URL has to carry three or more parameters to count at all, and the finding is only reported when the number of such URLs clears both a small floor and a share of the indexable pages the crawl read. A few filtered URLs on a large site stay below it by design.
Does Docket see URLs it did not crawl?
No. Every finding here is computed over the pages the crawl fetched that were indexable HTML — so the counts are a floor rather than a census. On a large site with a big parameter space, the more useful signal is whether the crawl kept finding new URL combinations until it ran out of budget.