Checkpointing is a pivotal technique in system research, with applications ranging from crash recovery to replay debugging. In this paper, we evaluate a number of in-memory checkpointing techniques and compare their properties. We also present a new compiler-based checkpointing scheme which improves state-of-the-art performance and memory guarantees in the general case. Our solution relies on a shadow state to efficiently store incremental in-memory checkpoints, at the cost of a smaller user-addressable virtual address space. Contrary to common belief, our results show that in-memory checkpointing can be implemented efficiently with moderate impact on production systems.