Why the query optimizer choose this bad execution plan?
My suggestion would be to change the ORDER BY id and use instead:

ORDER BY updated_at, id 


The secondary index on (updated_at) includes the id as well (which I assume is the primary key), so with this change there is no chance that the index won't be used, as it will be a perfect match for both the WHERE and the ORDER BY clause.

Bonus point, the query's plan will get rid of the sort as well.