Skip to content

timerfd

timerfd converts timer expiration events into file descriptor events. This makes timer handling fit naturally into an epoll event loop.

Why timerfd?

Traditional timer approaches can be awkward in event-driven programs:

Approach Limitation
sleep() Blocks the thread
Signal-based timer Requires async signal handling
Extra timer thread Requires synchronization
timerfd Integrates directly with epoll

Core Concept

timer expires
timerfd becomes readable
epoll_wait() returns
read(timerfd) to consume expirations

Important Behavior

Reading from a timerfd returns the number of expirations since the last read. It does not return a timestamp.

uint64_t expirations;
read(timer_fd, &expirations, sizeof(expirations));

Example:

timer interval = 1 second
read after 5 seconds → expirations = 5

Common Design Pattern

A scalable idle timeout design often uses:

single global timerfd
    +
per-client last_active timestamp

Instead of creating one timerfd per client.

timerfd tick
scan client list
compare now - last_active
close idle clients

Common Pitfalls

Pitfall Result
Forgetting to read the timerfd epoll keeps reporting the timerfd as readable
Creating too many timerfds More fd management complexity
Assuming read returns time Incorrect timeout logic
Blocking inside timer handler Delays all other event sources