Why it matters
Memstore sizing is one of the most impactful tuning choices in HBase. Too small and flushes are constant, creating many tiny HFiles that overwhelm compaction. Too large and RegionServer JVM heap is dominated by memstore, starving the block cache and slowing reads. Getting the size right is a workload-dependent balance.
Flush frequency also affects write latency indirectly. A flush blocks writes to the region briefly; frequent flushes mean frequent brief blocks.
The architecture
Each memstore is a ConcurrentSkipListMap keyed by row+column+timestamp, sorted by natural byte order. Writes append to this map in memory. There is one memstore per column family per region, so a region with three column families has three memstores.
Total memstore size across all regions on a RegionServer is capped at a global memory fraction (default 40 percent of RegionServer heap). When the global cap is exceeded, the RegionServer flushes the largest memstore to relieve pressure.
How it works end to end
Flush triggers: per-region threshold (default 128 MB), global RegionServer threshold, WAL size threshold (rare in normal operation), and periodic flush intervals. Any of these can trigger a flush on the target region.
The flush process serializes the memstore contents to a new HFile in HDFS. The HFile is sorted, indexed, and bloom-filter-equipped for fast future reads. During the flush, the memstore is snapshotted so that new writes can continue into a fresh memstore while the snapshot is being written out. This means writes are only briefly paused for the memstore switch.
Once the HFile is durably written, the memstore snapshot is discarded and the region's HFile set is updated to include the new file. Reads from now on can consult this HFile.