HTTP

Comparison

GET vs POST

Understand the fundamental differences between GET and POST HTTP methods. Learn about safety, idempotency, caching, request bodies, and when to use each.

Bottom line: GET is for reading data — safe, idempotent, cacheable, params in URL. POST is for creating/submitting data — not safe, not idempotent, body payload, never cached.

GET
vs
POST

The Core Difference

GET and POST are the two most-used HTTP methods, and they represent fundamentally different intentions:

This distinction isn’t just convention — it has real implications for caching, browser behavior, bookmarking, and API design.

Safety and Idempotency

These two properties define how methods should behave:

PropertyGETPOST
Safe (no side effects)✅ Yes❌ No
Idempotent (same result if repeated)✅ Yes❌ No
Cacheable✅ Yes❌ No (by default)

Safe means the request doesn’t modify server state. A GET request should be readable without consequence — you can make it 100 times and the server state stays the same.

Idempotent means making the same request multiple times produces the same result as making it once. GET is idempotent: fetching /users/42 ten times returns the same user ten times. POST is not: submitting an order form ten times creates ten orders.

Request Structure

GETPOST
ParametersQuery string (?key=value)Request body
BodyNot used (technically allowed, but ignored by most servers)Required for data
URL length limitYes (~2000 chars in practice)No practical limit
Visible in URLYesNo
Saved in browser historyYesNo
BookmarkableYesNo

GET parameters appear in the URL: /search?q=http+methods&page=2. This makes GET requests bookmarkable, shareable, and cacheable — but it also means sensitive data (passwords, tokens) must never go in a GET URL.

POST data goes in the request body, which is not stored in browser history and not visible in the URL bar. This makes POST appropriate for form submissions, file uploads, and any operation that changes server state.

Caching

GET responses can be cached by browsers, CDNs, and proxies. A Cache-Control: max-age=3600 on a GET response means the browser won’t re-request that URL for an hour.

POST responses are not cached by default. Even if you return Cache-Control: max-age=3600 on a POST response, most caches will ignore it. This is intentional — POST implies a state change, and caching state-changing operations would be dangerous.

Browser Behavior on Refresh

When a user refreshes a page loaded via GET, the browser simply re-sends the GET request silently.

When a user refreshes a page that was the result of a POST (like a form submission), the browser shows a warning: “Resending this form will resubmit your data.” This is the browser protecting the user from accidentally submitting a form twice.

The standard pattern to avoid this is the POST/Redirect/GET pattern: after a successful POST, redirect the user to a GET URL. The browser then loads the confirmation page via GET, and refreshing it is safe.

When to Use Each

Use GET when:

Use POST when:

Common Mistakes

Using GET for state-changing operations — e.g., /delete-user?id=42. This is dangerous because browsers, crawlers, and prefetch mechanisms can trigger GET requests without user intent. A crawler indexing your site could accidentally delete data.

Using POST for everything — some developers avoid GET because they don’t want parameters in the URL. This breaks caching, bookmarking, and sharing. Use GET for reads.

Putting sensitive data in GET parameters — passwords, tokens, and PII in query strings end up in server logs, browser history, and referrer headers. Always use POST (or headers) for sensitive data.