PostgreSQL: Add Minutes to Timestamp

When you’re building scheduling systems, setting cache expiration times, or calculating delivery windows, minute-precision matters. I’ve built appointment reminder systems where the difference between “notification sent on time” and “notification sent 5 minutes late” is the difference between a good user experience and a bad one. PostgreSQL’s interval arithmetic makes this trivial.

Adding minutes to timestamps is straightforward and works exactly like adding hours—you just use the same interval syntax with “minutes” instead. The beauty is that PostgreSQL handles all the boundary crossing automatically. Adding 45 minutes to 10:45 correctly gives you 11:30, not some weird time that breaks.

Quick Answer: Use + INTERVAL ‘… minutes’

To add minutes to a timestamp:

SELECT
    emp_id,
    first_name,
    created_at,
    created_at + INTERVAL '30 minutes' as thirty_min_later,
    created_at + INTERVAL '60 minutes' as one_hour_later
FROM employees
WHERE created_at IS NOT NULL
LIMIT 5;

Returns:

emp_id | first_name | created_at          | thirty_min_later    | one_hour_later
-------+------------+---------------------+---------------------+---------------------
     1 | James      | 2026-02-21 10:30:45 | 2026-02-21 11:00:45 | 2026-02-21 11:30:45
     2 | Mary       | 2026-02-20 14:15:30 | 2026-02-20 14:45:30 | 2026-02-20 15:15:30

That’s the pattern. Same + operator, just use 'minutes' instead of 'hours'.

How It Works

PostgreSQL’s INTERVAL type understands minutes the same way it understands hours, days, or seconds. When you add an interval to a timestamp, it calculates the exact future time, handling all the complexity of minute-to-hour transitions automatically.

Different Approaches & When to Use Them

Approach 1: Simple Minute Addition (Most Common)

SELECT
    appointment_time,
    appointment_time + INTERVAL '15 minutes' as reminder_time,
    appointment_time + INTERVAL '90 minutes' as follow_up_time
FROM appointments
WHERE appointment_time IS NOT NULL;

Best for: Most minute-level calculations.

Approach 2: Using MAKE_INTERVAL (For Columns)

When minutes come from a column:

SELECT
    order_id,
    created_at,
    delivery_window_minutes,
    created_at + MAKE_INTERVAL(mins => delivery_window_minutes) as delivery_deadline
FROM orders;

Much cleaner than string concatenation.

Best for: Dynamic minute values from columns.

Approach 3: Combine Minutes with Other Units

SELECT
    start_time,
    start_time + INTERVAL '2 hours 45 minutes' as end_time,
    start_time + INTERVAL '1 day 30 minutes' as next_day_plus_30min
FROM events;

Mix any units freely.

Approach 4: Subtract Minutes

SELECT
    deadline,
    deadline - INTERVAL '15 minutes' as warning_time,
    deadline - INTERVAL '60 minutes' as last_hour
FROM tasks;

Use - for subtraction.

Approach 5: Conditional Minutes

SELECT
    ticket_id,
    created_at,
    urgency,
    CASE
        WHEN urgency = 'Critical' THEN created_at + INTERVAL '5 minutes'
        WHEN urgency = 'High' THEN created_at + INTERVAL '15 minutes'
        ELSE created_at + INTERVAL '30 minutes'
    END as notification_time
FROM support_tickets;

Different minutes based on logic.

Real-World Example: Appointment Reminders

Send reminders 15 minutes before appointments:

SELECT
    appointment_id,
    patient_id,
    appointment_time,
    appointment_time - INTERVAL '15 minutes' as reminder_time,
    CASE
        WHEN CURRENT_TIMESTAMP >= (appointment_time - INTERVAL '15 minutes')
             AND CURRENT_TIMESTAMP < appointment_time
        THEN 'Send reminder now'
        WHEN CURRENT_TIMESTAMP >= appointment_time
        THEN 'Appointment passed'
        ELSE 'Not yet'
    END as reminder_status
FROM appointments
WHERE appointment_time > CURRENT_DATE
ORDER BY appointment_time;

Common Patterns

-- Quarter-hour increments
+ INTERVAL '15 minutes'
+ INTERVAL '30 minutes'
+ INTERVAL '45 minutes'

-- Combined
+ INTERVAL '1 hour 30 minutes'

-- Fractional
+ INTERVAL '45.5 minutes'

-- From variable
+ MAKE_INTERVAL(mins => column_name)

-- Negative (subtract)
- INTERVAL '10 minutes'

Performance Notes

Minute arithmetic is instant. PostgreSQL handles this at machine speed. Safe to use anywhere: WHERE clauses, ORDER BY, JOINs, aggregations.

FAQ

Q: How do I add fractional minutes (like 1.5 minutes)? A: Use decimal: INTERVAL '1.5 minutes' or MAKE_INTERVAL(mins => 1.5).

Q: Can I add minutes from a column? A: Yes: timestamp + MAKE_INTERVAL(mins => minutes_column).

Q: What about DST (daylight saving)? A: INTERVAL arithmetic doesn’t account for DST. It just adds duration. For DST-aware calculations, use timezone functions.

Q: Is ‘60 minutes’ the same as ‘1 hour’? A: Functionally yes, but 1 hour is conceptually clearer. Both add exactly 60 minutes.

Q: Can I get the difference in minutes between timestamps? A: Yes: (timestamp2 - timestamp1) / INTERVAL '1 minute' or EXTRACT(EPOCH FROM (ts2 - ts1)) / 60.

Q: Performance for adding many minutes? A: Same speed. Adding 1000 minutes takes the same instant as adding 1 minute.

Q: Does minute addition cross hour boundaries correctly? A: Yes, completely automatic. 10:50 + 15 minutes = 11:05 works perfectly.

Wrapping Up

Adding minutes to timestamps uses the same + operator as hours. For dynamic minutes from columns, use MAKE_INTERVAL(mins => column). Everything else handles itself automatically.

The key: PostgreSQL’s interval arithmetic handles all the boundary crossings for you.