Redirect vs URL Rewrite: What's the Difference?
The difference between a redirect and a URL rewrite: how each works, when to use one over the other, Apache and Nginx examples, performance considerations, and SEO impact.
A redirect and a URL rewrite both change where a request ends up, but they work in fundamentally different ways. A redirect tells the browser to go to a different URL. A rewrite tells the server to serve a different resource without the browser knowing. Understanding which one to use is the difference between clean URL architecture and broken user experiences.
For a broader look at redirect types and status codes, see the HTTP Redirect Guide.
The Core Difference
A redirect sends an HTTP response (301, 302, 307, or 308) back to the browser with a new URL in the Location header. The browser then makes a second request to that new URL. The user sees the URL change in the address bar.
A rewrite happens entirely on the server. The server receives a request for one URL, internally maps it to a different file or resource, and serves the response. The browser never knows the internal mapping happened. The URL in the address bar stays exactly the same.
Redirect (two round trips):
Browser requests /old-page
Server responds: 301, Location: /new-page
Browser requests /new-page
Server responds: 200, here is the content
Rewrite (one round trip):
Browser requests /products/widget
Server internally maps to /index.php?category=products&item=widget
Server responds: 200, here is the content
Browser still shows /products/widget
The redirect involves two HTTP requests. The rewrite involves one. This distinction drives every practical difference between the two.
How Redirects Work
When a server issues a redirect, it sends back a response with a 3xx status code and a Location header. The browser reads the header, discards the original response, and makes a new request to the URL in the header.
The status code tells the browser (and search engines) whether the redirect is permanent or temporary:
- 301 Moved Permanently: The old URL is gone for good. Update your bookmarks and links. See 301 Moved Permanently Explained.
- 302 Found: The old URL is temporarily pointing elsewhere. Keep the original. See 301 vs 302 Redirects.
- 307 Temporary Redirect: Same as 302, but the request method must not change.
- 308 Permanent Redirect: Same as 301, but the request method must not change.
The browser sees the new URL. Search engines see the new URL. Analytics tools record the new URL. The redirect is visible to everyone.
Apache Redirect Example
In Apache, you can configure redirects in .htaccess or in the virtual host configuration. For a full walkthrough, see the htaccess Redirect Guide.
# Simple redirect
Redirect 301 /old-page /new-page
# Using RewriteRule with the R flag
RewriteEngine On
RewriteRule ^old-page$ /new-page [R=301,L]
The Redirect directive is the simplest approach. The RewriteRule with the [R] flag gives you more flexibility with pattern matching. Both produce the same result: a 301 response to the browser.
Nginx Redirect Example
In Nginx, redirects are configured in the server block. See the Nginx Redirect Guide for detailed examples.
# Simple redirect
location = /old-page {
return 301 /new-page;
}
# Pattern-based redirect
location ~ ^/blog/(\d{4})/(.+)$ {
return 301 /articles/$2;
}
The return directive is preferred over rewrite with the redirect flag because it is more explicit and slightly faster.
How Rewrites Work
A rewrite maps a requested URL to a different internal path. The web server processes the request as if the client had asked for the internal path, but the client never sees the mapping. The URL in the browser stays the same.
Rewrites are the foundation of clean URLs. When you visit example.com/products/widget, the server might internally serve /index.php?type=product&slug=widget. The user sees a clean, readable URL. The application receives the parameters it needs.
Apache Rewrite Example
RewriteEngine On
# Clean URL to query string
RewriteRule ^products/([a-z0-9-]+)$ /index.php?type=product&slug=$1 [L]
# Remove .php extension
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ $1.php [L]
Notice the absence of the [R] flag. Without it, RewriteRule performs an internal rewrite, not a redirect. The [L] flag means "last rule," telling Apache to stop processing further rewrite rules.
Nginx Rewrite Example
# Clean URL to query string
location /products/ {
rewrite ^/products/([a-z0-9-]+)$ /index.php?type=product&slug=$1 last;
}
# Try static file, then directory, then fallback to index.php
location / {
try_files $uri $uri/ /index.php?$query_string;
}
The try_files directive in Nginx is the most common rewrite pattern. It tries to serve a static file, then a directory, then falls back to a PHP (or other) handler. This is how most CMS and framework-based sites work: the web server rewrites all requests to a single entry point that handles routing internally.
When to Use a Redirect
Use a redirect when the URL needs to change from the user's perspective.
Moved content. A page that used to live at /about-us now lives at /company. Anyone with the old URL bookmarked, linked, or indexed needs to be sent to the new location. A 301 redirect updates search engine indexes and passes link equity.
Domain changes. You are moving from oldbrand.com to newbrand.com. Every URL on the old domain needs a redirect to the corresponding URL on the new domain.
Protocol changes. Redirecting HTTP to HTTPS, or redirecting www to the bare domain (or vice versa). These are canonical URL decisions that require the browser to know about the change.
Consolidating duplicate URLs. If the same content is accessible at /page, /page/, and /page/index.html, pick one canonical URL and redirect the others to it.
Retired content. A product page for something you no longer sell, redirected to a relevant category page or a successor product.
When to Use a Rewrite
Use a rewrite when the URL should stay the same but the server needs to serve content from a different internal location.
Clean URLs. Mapping /products/widget to /index.php?product=widget so users see readable URLs while the application receives its expected parameters.
Framework routing. Most web frameworks (Laravel, Rails, Express, Django, Next.js) use a rewrite to route all requests to a single entry point. The framework then handles URL parsing and routing internally.
API versioning. Internally routing /api/v2/users to a different handler than /api/v1/users without exposing the internal file structure.
A/B testing (server-side). Serving different content at the same URL based on a cookie, header, or other criteria. The URL stays the same. The server decides which version to render. This is different from redirect-based A/B testing, where users are sent to different URLs.
Load distribution. Rewriting requests to different backend servers based on the URL path, without the client knowing which server handled the request.
Performance Differences
Redirects are slower than rewrites because they require an extra HTTP round trip.
When a browser encounters a redirect, it must:
- Send the initial request
- Receive the redirect response
- Parse the
Locationheader - Perform DNS resolution for the new URL (if the domain is different)
- Establish a new TCP connection (if the server is different)
- Send a new request
- Receive the actual response
A rewrite skips steps 2 through 6. The server handles the mapping internally and responds with the content in a single round trip.
For a single redirect, the extra latency is usually 50 to 200 milliseconds depending on the server location and connection quality. That is noticeable but not dramatic. The problem compounds with redirect chains, where one redirect leads to another. Each hop adds another round trip. A three-hop redirect chain can add 300 to 600 milliseconds of latency, which meaningfully affects page load times and user experience.
Rewrites have essentially zero performance overhead. The URL mapping happens in memory on the server before the request is processed. The difference between serving /index.php directly and rewriting /products/widget to /index.php?slug=widget is negligible.
SEO Implications
Redirects and rewrites have different effects on how search engines see your site.
Redirects and SEO
Search engines follow redirects and update their indexes based on the redirect type. A 301 redirect tells Google to replace the old URL with the new one in its index and to transfer all ranking signals. A 302 tells Google to keep the old URL indexed. Choosing the wrong type can cause ranking issues. See 301 vs 302 Redirects for the full breakdown.
Redirect chains (A redirects to B, B redirects to C) dilute crawl efficiency. Google follows redirect chains but has said it will follow a limited number of hops before giving up. Keep chains to a minimum.
Rewrites and SEO
Rewrites are invisible to search engines. Google sees the clean URL and indexes it. It never knows about the internal mapping to a PHP file or application handler. This is exactly what you want: the URL that appears in search results is the clean, readable URL.
The SEO concern with rewrites is making sure the same content is not accessible at multiple URLs. If /products/widget and /index.php?product=widget both return the same content, you have a duplicate content issue. Configure your rewrite rules so that the internal URL either returns a 404 or redirects to the clean URL.
Common Mistakes
Using a Redirect When You Need a Rewrite
If you want clean URLs but configure redirects instead of rewrites, users will see the ugly internal URL in their browser. /products/widget redirects to /index.php?product=widget, and that is what appears in the address bar and search results. Use a rewrite to keep the clean URL visible.
Using a Rewrite When You Need a Redirect
If you move content to a new URL and use a rewrite instead of a redirect, search engines never learn about the move. They continue to index the old URL, and link equity stays on the old URL. Users who bookmarked the old URL get served content at a URL that does not match what they see in your navigation. Use a redirect when the URL genuinely needs to change.
Confusing Apache Rewrite Flags
In Apache's mod_rewrite, the difference between a rewrite and a redirect is a single flag: [R]. Forgetting this flag means you get a rewrite when you wanted a redirect. Adding it when you did not mean to turns your clean URL rewrite into a redirect loop.
# This is a REWRITE (internal)
RewriteRule ^products/(.+)$ /index.php?slug=$1 [L]
# This is a REDIRECT (external)
RewriteRule ^products/(.+)$ /index.php?slug=$1 [R=301,L]
Creating Infinite Loops
A common mistake is writing a rewrite or redirect rule that matches its own output. The request matches the rule, gets rewritten or redirected, the new URL matches the same rule again, and the server loops. Apache has a default limit of 10 internal rewrites before it returns a 500 error. Browsers give up after a few redirect hops and show an "ERR_TOO_MANY_REDIRECTS" error.
Use conditions (RewriteCond in Apache, if in Nginx) to prevent rules from matching their own output.
Quick Decision Rule
If the URL should change in the browser's address bar, use a redirect. If the URL should stay the same while the server fetches content from a different location, use a rewrite.
Summary
Redirects and rewrites solve different problems. Redirects change the URL the user sees and tell search engines about the move. Rewrites hide internal server routing from users and search engines. Most sites use both: rewrites for clean URL routing, and redirects for content that has genuinely moved.
The key is choosing the right tool for each situation. If you use a redirect where you need a rewrite, you expose internal URLs. If you use a rewrite where you need a redirect, you hide necessary URL changes from search engines. Get the choice right, and your URL structure stays clean, your SEO stays healthy, and your users never see the plumbing.
Trace any redirect chain instantly
See every hop, status code, and header in a redirect chain. Verify that your redirects are working as expected.
Try Redirect Tracer