Okay, so today I wanted to figure out the deal with “h2” and “h2r”. I’d seen them pop up in different places and, honestly, I wasn’t 100% sure what the difference was. So, I decided to dig in and get my hands dirty.

First, I started by just Googling both terms separately. I figured I’d get the basic definitions out of the way. “h2” seemed pretty straightforward – it’s a database, an in-memory one, written in Java. Lots of folks use it for testing and development because it’s lightweight and easy to spin up.
Then I searched for “h2r”. This one was a little less obvious at first. The results were a bit all over the place, but I eventually found some forum posts and documentation hinting that it had something to do with connecting to a remote H2 database.
My Experiment Setup
To really understand this, I decided to set up a little experiment. Here’s what I did:
- I downloaded the H2 database JAR file from their official website. I made sure to grab the latest stable release.
- I created a simple Java project in my IDE (I’m using IntelliJ, but Eclipse or whatever works fine).
- I added the H2 JAR file as a dependency to my project. Pretty standard stuff.
Playing with ‘h2’ (Local Database)
First, I wanted to get comfortable with just using a regular, local H2 database. I wrote some basic Java code to connect to an in-memory database using the JDBC URL: jdbc:h2:mem:testdb
. I created a simple table, inserted some data, and ran a few queries. All good, worked like a charm! This confirmed what I’d read – “h2” by itself lets you work with a database that lives entirely in your computer’s memory.
Tackling ‘h2r’ (Remote Connection)
Now for the “h2r” part.I started an h2 database server.

Then I changed my JDBC URL to something like jdbc:h2:tcp://localhost/~/test
. I Created the “test” databse in my local machine. This, I figured, was telling H2 to connect to a remote database (even though it was still on my machine, it was running as a separate process).
I ran my code again, and… boom! It connected! I could see the same table I’d created earlier, access the data, everything. This is where it clicked: “h2r” isn’t really a separate thing; it’s just a way of using H2 to connect to a database that’s running as a server, rather than embedded directly in your application’s memory.
So it’s more about how you’re using H2, not a fundamentally different version of the * can be local or * “r” just implies that you’re setting it up for remote connections.
I felt pretty good about figuring this out. It’s one of those things that seems confusing at first, but once you play around with it, it becomes much clearer. Hope this little walkthrough of my experiment helps someone else out there!
