HTTP

Cookie Attribute

Expires

Learn how the Expires cookie attribute sets an absolute expiration date. Understand date formats, timezone handling, and when to use Expires vs Max-Age.

5 min read beginner Try in Playground

TL;DR: Sets an absolute expiration date for cookies using HTTP date format - use for specific deadlines, but prefer Max-Age for relative expiration times.

What is the Expires Attribute?

The Expires attribute sets an absolute date and time when a cookie should be deleted. It’s like putting an expiration date on food - the browser automatically removes the cookie when that moment arrives. Without this attribute (or Max-Age), cookies are deleted when the browser session ends.

This attribute is essential for controlling cookie lifetime and managing storage space.

How It Works

Deleted when browser closes:

Set-Cookie: sessionId=abc123
# Expires: When browser session ends
```text

### Persistent Cookie (With Expires)

Deleted at specific date/time:

```http
Set-Cookie: rememberMe=true; Expires=Wed, 15 Jan 2026 12:00:00 GMT
# Expires: January 15, 2026 at noon GMT

Date Format

Expires uses HTTP date format (RFC 7231):

Expires=Day, DD Mon YYYY HH:MM:SS GMT
```text

**Examples:**

```http
Expires=Wed, 15 Jan 2025 12:00:00 GMT
Expires=Fri, 31 Dec 2025 23:59:59 GMT
Expires=Mon, 01 Jan 2024 00:00:00 GMT

Important: Always use GMT timezone, not local time.

Real-World Examples

Remember Me Login

Keep user logged in for 30 days:

Set-Cookie: rememberToken=xyz789; Expires=Thu, 14 Feb 2025 10:30:00 GMT; Secure; HttpOnly
```text

### User Preferences

Store theme preference for 1 year:

```http
Set-Cookie: theme=dark; Expires=Sat, 15 Jan 2026 12:00:00 GMT; Path=/

Shopping Cart

Keep cart items for 1 week:

Set-Cookie: cartId=cart456; Expires=Wed, 22 Jan 2025 15:42:30 GMT; SameSite=Lax
```text

### Temporary Banner Dismissal

Hide promotional banner for 24 hours:

```http
Set-Cookie: bannerDismissed=promo2025; Expires=Thu, 16 Jan 2025 10:00:00 GMT

Analytics Tracking

Track user for 2 years:

Set-Cookie: trackingId=user123; Expires=Sun, 15 Jan 2027 00:00:00 GMT; SameSite=Lax
```text

## Expires vs Max-Age

Both control cookie lifetime, but work differently:

### Expires (Absolute Time)

```http
Set-Cookie: data=value; Expires=Wed, 15 Jan 2025 12:00:00 GMT
  • Specific date and time
  • Affected by client clock changes
  • Older browsers support

Max-Age (Relative Time)

Set-Cookie: data=value; Max-Age=86400
```javascript

- Seconds from now
- Not affected by clock changes
- Modern browsers prefer this

**Priority:** If both are present, Max-Age takes precedence.

## Generating Expires Dates

### JavaScript

```javascript
// 30 days from now
const expires = new Date()
expires.setDate(expires.getDate() + 30)
const expiresString = expires.toUTCString()
// "Wed, 15 Feb 2025 10:30:00 GMT"

document.cookie = `rememberMe=true; Expires=${expiresString}`

Node.js/Express

// 7 days from now
const expires = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)

res.cookie('cartId', 'cart123', {
  expires: expires,
  httpOnly: true
})
```javascript

### Python

```python
from datetime import datetime, timedelta

# 1 year from now
expires = datetime.utcnow() + timedelta(days=365)
expires_string = expires.strftime('%a, %d %b %Y %H:%M:%S GMT')

response.set_cookie(
    'preferences',
    'theme=dark',
    expires=expires_string
)

PHP

// 30 days from now
$expires = gmdate('D, d M Y H:i:s T', time() + (30 * 24 * 60 * 60));

setcookie('userId', '123', [
    'expires' => $expires,
    'secure' => true,
    'httponly' => true
]);
```text

## Deleting Cookies

Set expiration date in the past:

```http
Set-Cookie: oldCookie=; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Path=/

JavaScript:

// Delete cookie
document.cookie = 'sessionId=; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Path=/'
```text

**Express.js:**

```javascript
// Delete cookie
res.clearCookie('sessionId', { path: '/' })

Common Expiration Periods

Session Cookies

# No Expires = session only
Set-Cookie: tempData=value
```text

### Short-term (Minutes to Hours)

```http
# 1 hour
Set-Cookie: csrfToken=abc; Expires=Wed, 15 Jan 2025 11:00:00 GMT

# 24 hours
Set-Cookie: dailyLimit=reached; Expires=Thu, 16 Jan 2025 10:00:00 GMT

Medium-term (Days to Weeks)

# 7 days
Set-Cookie: shoppingCart=items; Expires=Wed, 22 Jan 2025 10:00:00 GMT

# 30 days
Set-Cookie: rememberMe=true; Expires=Thu, 14 Feb 2025 10:00:00 GMT
```text

### Long-term (Months to Years)

```http
# 1 year
Set-Cookie: userId=123; Expires=Thu, 15 Jan 2026 10:00:00 GMT

# 2 years (maximum recommended)
Set-Cookie: trackingId=xyz; Expires=Sat, 15 Jan 2027 10:00:00 GMT

Security Considerations

Sensitive Data Expiration

Keep short expiration for sensitive cookies:

✅ Short-lived session:
Set-Cookie: sessionId=secret; Expires=Wed, 15 Jan 2025 11:00:00 GMT; Secure; HttpOnly

❌ Long-lived sensitive data:
Set-Cookie: sessionId=secret; Expires=Wed, 15 Jan 2027 10:00:00 GMT
```text

### Clock Synchronization

Client clock differences can cause issues:

```javascript
// Problem: Client clock is wrong
// Server sets: Expires=Wed, 15 Jan 2025 12:00:00 GMT
// Client thinks it's: Wed, 15 Jan 2025 13:00:00 GMT
// Cookie appears expired immediately

// Solution: Use Max-Age instead for critical cookies
res.cookie('data', value, { maxAge: 86400000 }) // 24 hours

Best Practices

1. Use appropriate expiration times:

Session data: No Expires (session only)
Authentication: 1-24 hours
Preferences: 30 days to 1 year
Tracking: Maximum 2 years
```text

**2. Prefer Max-Age for modern applications:**

```http
✅ Max-Age=86400  (not affected by clock skew)
⚠️ Expires=Wed, 15 Jan 2025 12:00:00 GMT  (can have clock issues)

3. Always use GMT timezone:

✅ Expires=Wed, 15 Jan 2025 12:00:00 GMT
❌ Expires=Wed, 15 Jan 2025 12:00:00 PST
```text

**4. Include both for maximum compatibility:**

```http
Set-Cookie: data=value; Max-Age=86400; Expires=Thu, 16 Jan 2025 10:00:00 GMT

5. Clean up expired cookies:

// Server-side cleanup
app.use((req, res, next) => {
  // Remove expired session data
  cleanupExpiredSessions()
  next()
})
```javascript

## Troubleshooting

### Cookie Expires Immediately

```javascript
// Problem: Wrong timezone
const expires = new Date('2025-01-15 12:00:00 PST') // Wrong!

// Solution: Use UTC
const expires = new Date('2025-01-15T12:00:00Z') // Correct
// Problem: Date in future but wrong format
Set-Cookie: data=value; Expires=January 15, 2025  // Invalid format

// Solution: Use proper HTTP date format
Set-Cookie: data=value; Expires=Wed, 15 Jan 2025 12:00:00 GMT
```javascript

### Inconsistent Expiration

```javascript
// Problem: Different expiration times for related cookies
Set-Cookie: sessionId=abc; Expires=Wed, 15 Jan 2025 12:00:00 GMT
Set-Cookie: userId=123; Expires=Thu, 16 Jan 2025 12:00:00 GMT

// Solution: Use same expiration for related cookies
const expires = new Date(Date.now() + 24 * 60 * 60 * 1000).toUTCString()
Set-Cookie: sessionId=abc; Expires=${expires}
Set-Cookie: userId=123; Expires=${expires}
  • Max-Age - Alternative relative expiration method
  • Secure - HTTPS-only transmission
  • HttpOnly - Prevent JavaScript access
  • SameSite - Cross-site request control

Frequently Asked Questions

What is the Expires cookie attribute?

Expires sets an absolute date/time when the cookie expires. After this time, browsers delete the cookie. Without Expires or Max-Age, cookies are session cookies.

What format does Expires use?

HTTP date format in GMT: Expires=Wed, 21 Oct 2026 07:28:00 GMT. The date must be in the future for the cookie to persist.

Should I use Expires or Max-Age?

Max-Age is preferred as it uses relative seconds and avoids timezone issues. Expires requires absolute dates. Use Max-Age for new code.

How do I delete a cookie?

Set Expires to a past date or Max-Age=0. The browser will delete the cookie immediately. You must match the original Path and Domain.

Keep Learning