This isn't like mongodb's non-durable-by-default writes. No, the "buffering" here is done client-side. So it really wasn't hitting the database at all (until the client teardown phase, well after the latency that is being graphed here was measured).
cleanup calls flushCommits. So all requests are there. No get requests are served from the client's buffers so all of those must hit the region server. In addition the client side write buffer size is 12mb. So we're not talking about all requests being buffered at a time.
This may or may not be what is needed for your application so autoFlush is a per-client setting (HBase actually defaults it to on). Deferred log flushing is similar, though it's a per table setting.
Average latency is NOT correct because YCSB latency is measured per-insert, not averaged over the total runtime. Here is the code from DBWrapper.insert:
long st=System.nanoTime();
int res=_db.insert(table,key,values);
long en=System.nanoTime();
_measurements.measure("INSERT",(int)((en-st)/1000));
... where db.insert makes the htable.put call we're talking about.
The HBase default is correct for what YCSB is trying to measure ("live" updates, i.e., the update should be readable from the regionserver afterwards), but someone submitted a YCSB patch to override the default to make latency look better time some time ago, and most benchmarks including this one have inherited the mistake.
The client will block after the buffer is full, and will wait until the outstanding requests are ack'd from the server. So the times will still be pretty close to correct. Only the last few puts won't be timed.