В сущности лучше всего видится использование сервиса на основе event loop. Технически - libevent. Вокруг этой библиотеки есть и Node.js, и ReactPHP, и прочие ЯП. Хорошо это тем, что не грузит систему. Соответственно, можно довольно легко написать своего демона, который будет регистрировать таймеры и выполнять обработчики (типа onExpire, getRemainingTime).
Для связи с демоном использовать менеджер очередей, например ZeroMQ или RabbitMQ, или Redis