Welcome!
Welcome to my adventure series on the NATS JetStream Key/Value Store!
This series is here to help complete beginners, step by step - no prior knowledge needed (really, trust me, I didn't have much when I started either!).
No one begins as an expert - that's the beauty of learning! By the end of this journey, you'll not only grasp the basics of the NATS JetStream KV Store but also build a fully functional multiplayer Tic-Tac-Toe game, capable of handling multiple concurrent games.
It will end up looking something like this.
This isn't going to be a comprehensive deep dive - if that's what you're looking for, Synadia has a ton of great videos that cover NATS as deep as you want to go.
No - this is for someone like me: someone who's occasionally a bit lazy and appreciates being spoon-fed the basics. Is that a bad thing or a hidden virtue? I'll let you decide. We're going for a "getting-your-feet-wet" practical usage of the KV Store.
How did we get here?
For quite sometime I didn't even know what NATS was, I had seen it in certain books I was reading or on a YouTube video the algorithm decided to toss at me yet it wasn't until a very talented coworker had made me aware of it. He was able to build very impressive applications extremely fast, and I didn't understand how. He was humble and would simply say:
"Everyone just makes things more complicated than they have to be."
or
"You're probably just over-complicating it."
I didn't believe him. How did this guy move so quick. Was he one of the legendary 10x programmers we all hear about? I don't know; maybe (yes) - but he did let me in on something.
"Sometimes, certain tools are just better than others."
(We can come back to this one.)
Well, what tools? I want that kind of superpower! One tool he often raved about was NATS, so I finally decided to see what all the fuss was about.
Alright come on! What the heck is NATS?!
Alright let's cut to the chase
Ok, so…what does that mean??
NATS is a single technology composed of various parts that can work in cohesion but you can use parts like Jetstream on their own. It's powerful so just boiling it down to a little list wouldn't do it justice. However; I'm still going to do that; for US!
NATS Core
NATS Core is… well the Core. The fundamental backbone of NATS. There's a lot there but let's try to boil it down.
NATS Core is like live TV or a live broadcast - offering Publish/Subscribe and Request/Reply patterns with an ephemeral nature. If you're not tuned in when the message is broadcast, you miss it. There's no recording, no rewind - just real-time communication. We'll dive deeper into NATS Core in another adventure.
NATS JetStream
NATS Jetstream is built on top of NATS Core.
NATS JetStream is like a DVR or streaming service for your messaging system. It provides features such as Streams, Consumers, an Object Store, and, most importantly for our exploration, the Key Value Store.
Think of the K/V Store like a locker system where you can store and retrieve small pieces of information by key (like storing a favorite recipe or settings for your TV).
Key Takeaways
- NATS Core is fast, lightweight, and ideal for real-time communication where persistence isn't needed.
- NATS JetStream adds persistence, replay, and storage capabilities, making it ideal for use cases requiring message durability or more extensive data management.
There's a lot more to it but we'll just be succinct because we have so many other adventures to go on!
When can we start?
Right now! Let's do it! We need to get setup to use Jetstream. Since we'll be coding in Go later, we'll install the NATS CLI using Go as well. Here's the lowdown on getting Go, the NATS CLI, and the NATS Server up and running on a Debian Linux system:
Install Go
Download the Go Archive
Head over to the official Go downloads page. Find the latest stable release for Linux (it will be a .tar.gz
file, probably something like go1.XX.linux-amd64.tar.gz
). Copy the link to that file.
Open a Terminal:
Fire up your terminal.
Download the Archive (using wget
)
Paste the link you copied into the following command, replacing the example filename with the actual filename:
$ wget https://go.dev/dl/go1.XX.linux-amd64.tar.gz
Extract the Archive
$ sudo tar -xzvf go1.XX.linux-amd64.tar.gz -C /usr/local
(This extracts Go to /usr/local
which is a pretty standard location).
Set Up Your Path
You need to add Go's bin directory to your system's PATH. Open your ~/.bashrc
file (or ~/.zshrc
if you use Zsh) with a text editor:
$ nano ~/.bashrc # Or vi ~/.bashrc, or gedit ~/.bashrc, etc.
Add the Path
Add the following line to the end of the file:
$ export PATH=$PATH:/usr/local/go/bin
Save and Source
Save the file and then run:
$ source ~/.bashrc
Verify the Installation
Check that Go is installed correctly by running:
$ go version
Install NATS CLI
Download the NATS CLI binary
$ wget https://github.com/nats-io/natscli/releases/latest/download/nats-linux-amd64
Make the binary executable
$ chmod +x nats-linux-amd64
Move the binary to a directory in your PATH
$ sudo mv nats-linux-amd64 /usr/local/bin/nats
Verify installation
$ nats --version
Install NATS Server
Download the NATS Server binary
$ wget https://github.com/nats-io/nats-server/releases/latest/download/nats-server-linux-amd64
Make the binary executable
$ chmod +x nats-server-linux-amd64
Move the binary to a directory in your PATH
$ sudo mv nats-server-linux-amd64 /usr/local/bin/nats-server
Verify installation
$ nats-server --version
Start NATS Server
Run the server:
$ nats-server
Sweet. It looks like we're cooking!
So let's do some stuff!
Open your terminal and locate the nats-server binary we installed.
Follow along with me!
$ ./nats-server
[26351] 2025/01/17 23:42:47.658293 [INF] Starting nats-server
[26351] 2025/01/17 23:42:47.658708 [INF] Version: 2.10.20
[26351] 2025/01/17 23:42:47.658719 [INF] Git: [7140387]
[26351] 2025/01/17 23:42:47.658729 [INF] Name: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
[26351] 2025/01/17 23:42:47.658739 [INF] ID: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
[26351] 2025/01/17 23:42:47.660565 [INF] Listening for client connections on 0.0.0.0:XXXX
[26351] 2025/01/17 23:42:47.661437 [INF] Server is ready
# You will see that the server is up and ready.
# Info will be displayed about our NATS Server.
# Version: 2.10.20 # Name of the Key-Value bucket.
# Git: [7140387] # Git Commit Hash of the nats-server source code
# Name: # NATS Server Name.
# ID: # NATS Server ID
# Listening for ... # Address and Port nats-server is listening on.
# # - Listening on all available network interfaces
Ok so NATS Server is running, noice! Only one issue, we're not running with Jetstream. You can tell by opening another terminal window and checking.
Let's check for more information on our server.
$ nats account info
Account Information
User:
Account: $G
Expires: never
Client ID: 5
Client IP: 127.0.0.1
RTT: 87µs
Headers Supported: true
Maximum Payload: 1.0 MiB
Connected URL: nats://127.0.0.1:4222
Connected Address: 127.0.0.1:4222
Connected Server ID: NDQH5BXP4G6HACAE3VFZLD6OUYJB6GF3YEUP3S25YA4J34U2RU7SJ4DK
Connected Server Version: 2.10.20
TLS Connection: no
Could not obtain account information: nats: jetstream not enabled
Notice that it tells us that Jetstream is not enabled. Oops! Ok - no biggie. Just go to the terminal where NATS Server is running and CTRL-C
. Let's try this again!
$ ./nats-server -jetstream or -js
# You'll see something like this now.
[27511] 2025/01/17 23:59:29.453968 [INF] Starting nats-server
[27511] 2025/01/17 23:59:29.454436 [INF] Version: 2.10.20
[27511] 2025/01/17 23:59:29.454448 [INF] Git: [7140387]
[27511] 2025/01/17 23:59:29.454458 [INF] Name: NAI6RRCXFGU7GESGBIZJSXHNU2N2UGTOB6BQYEOZDKW2CP76BRNZXMK3
[27511] 2025/01/17 23:59:29.454474 [INF] Node: 3BBAzCdl
[27511] 2025/01/17 23:59:29.454483 [INF] ID: NAI6RRCXFGU7GESGBIZJSXHNU2N2UGTOB6BQYEOZDKW2CP76BRNZXMK3
[27511] 2025/01/17 23:59:29.456007 [INF] Starting JetStream
[27511] 2025/01/17 23:59:29.456570 [INF] _ ___ _____ ___ _____ ___ ___ _ __ __
[27511] 2025/01/17 23:59:29.456598 [INF] _ | | __|_ _/ __|_ _| _ \ __| /_\ | \/ |
[27511] 2025/01/17 23:59:29.456613 [INF] | || | _| | | \__ \ | | | / _| / _ \| |\/| |
[27511] 2025/01/17 23:59:29.456631 [INF] \__/|___| |_| |___/ |_| |_|_\___/_/ \_\_| |_|
[27511] 2025/01/17 23:59:29.456651 [INF]
[27511] 2025/01/17 23:59:29.456669 [INF] https://docs.nats.io/jetstream
[27511] 2025/01/17 23:59:29.456680 [INF]
[27511] 2025/01/17 23:59:29.456692 [INF] ---------------- JETSTREAM ----------------
[27511] 2025/01/17 23:59:29.456709 [INF] Max Memory: 11.53 GB
[27511] 2025/01/17 23:59:29.456730 [INF] Max Storage: 281.91 GB
[27511] 2025/01/17 23:59:29.456751 [INF] Store Directory: "/tmp/nats/jetstream"
[27511] 2025/01/17 23:59:29.456771 [INF] -------------------------------------------
[27511] 2025/01/17 23:59:29.457933 [INF] Listening for client connections on 0.0.0.0:4222
[27511] 2025/01/17 23:59:29.458739 [INF] Server is ready
Ok - we see Jetstream in there! Let's try the account command again.
$ nats account info
Account Information
User:
Account: $G
Expires: never
Client ID: 350
Client IP: 127.0.0.1
RTT: 122µs
Headers Supported: true
Maximum Payload: 1.0 MiB
Connected URL: nats://127.0.0.1:4222
Connected Address: 127.0.0.1:4222
Connected Server ID: NDJ4PFQB5RVJXFDKC6G7ZZRDBEH3M4OMEUMDQFXJE5BFNSALQLAHMTEV
Connected Server Version: 2.10.20
TLS Connection: no
JetStream Account Information:
Account Usage:
Storage: 0 B
Memory: 0 B
Streams: 3
Consumers: 0
Account Limits:
Max Message Payload: 1.0 MiB
Tier: Default:
Configuration Requirements:
Stream Requires Max Bytes Set: false
Consumer Maximum Ack Pending: Unlimited
Stream Resource Usage Limits:
Memory: 0 B of Unlimited
Memory Per Stream: Unlimited
Storage: 0 B of Unlimited
Storage Per Stream: Unlimited
Streams: 3 of Unlimited
Consumers: 0 of Unlimited
Wow. Ok. There's a ton of new information about Jetstream. We will go into this in another adventure. For now let's just keep pushing!
Sorry I had to trick you like that but look - we're learning! NATS Server is now up and running with Jetstream! It kind of just works.
Anyhow, I hate to say it but I feel like we're rather low down on this page and nobody wants to scroll this far! So we shall continue our adventure in Part 2!
See ya there!
Top comments (0)