If you're using linux using IPV4 have a look at the following parameters in /proc/sys/net/ipv4:
tcp_tw_recycle
tcp_tw_reuse
Tuning those will help in allowing faster re-use of sockets in the TIME_WAIT state. This matters because at the defaults your sockets will linger for a long time before being allowed to be re-used (as per the RFC). Technically this is the correct behaviour but it can quickly become a bottle-neck.
Ulimit max open files per process:
ulimit -n 50000
The default is just 1,024, and that's not nearly enough to keep varnish working hard.
Those are the first things to look at, there are many more once you start to bottom out again, but this will get you started.
A good way to see if you've got your kernel tuned properly is when varnish starts to approach the limits of your hardware, I've seen it do well over 600Mbps on an otherwise unloaded box.
How about cache it once at write-time, then again whenever you edit it?
I did not use varnish at the time, but I basically kept up with the load. My pages were cached with an in-memory cache in the app layer, which worked well enough, I guess. As blog.jrock.us mentions, I was unhappy with the design of my software, so I took it down. Two years later, I almost know what a good design is, and so I should have a blog again soon. But I digress :)
(I'm also a big fan of Varnish. I tried it out this weekend on a site that basically serves an HTML file that says "hello world". Apache can do about 11,000 requests a second, but Varnish can serve 15,000 requests a second. Excellent!)