# Improving my dev workflow - Save thy memory ⚡️

### Problem

For my dev flow, I need to run a [ring](https://github.com/ring-clojure/ring) backend server, [figwheel](https://github.com/bhauman/lein-figwheel) for frontend hot loading, and a [datomic](https://www.datomic.com/) database. For the uninitiated, each of them is running on a different JVM and now add IntelliJ(curse me for not learning Emacs), a [browser](https://brave.com/) with a million tabs, [Spotify](https://open.spotify.com/playlist/3cS7qlmc9CgKLqPdSgNeIW?si=npZJ7GEaTwec7OfE_bq8NA), Slack, Zoom and there's no difference between a toaster and Macbook.

Although you can control the JVM memory usage, it's easy to run into memory issues and I'm yet to find a decent balance between performance and memory usage.

macOS extensively uses swap to address memory overflow but SSD's lifespan decreases with each write and more importantly, it's slower than RAM, which results in slower operations and workflows.

### Solution

Reduce the memory allocation pool by tuning JVM with [Xms option](https://docs.oracle.com/cd/E21764_01/web.1111/e13814/jvm_tuning.htm#PERFM161)

#### Putting all things in a server&#x20;

Get your code on a [20$ machine](https://www.linode.com/pricing/) which gives you 2CPUs and 4 gigs of RAM. I found this enough and [added more swap](https://askubuntu.com/questions/1075505/how-do-i-increase-swapfile-in-ubuntu-18-04) just in case. Setup your Nginx ssl and certificates if any and start the servers.

#### Connecting to remote machine

You don't want to swap local URLs with server URLs and run the whole process; there's something better i.e [ssh port forwarding](https://www.ssh.com/ssh/tunneling/example).  Start port forwarding with this:

```
ssh -L port-local-1:localhost:remote-port-1 -L port-local-2:localhost:port-local-2 root@server-ip
```

Every request to `localhost:port-1` will forward to `server's port-1`&#x20;

#### Syncing changes

Now for every change you make to your IntelliJ you want to see your changes hot loaded. All intelli-j products have [file watchers](https://www.jetbrains.com/help/idea/using-file-watchers.html#ws_creating_file_watchers). File watchers allow you to run a script when a file is saved, which is exactly what we need. Add a file watcher which [rsync's](https://www.digitalocean.com/community/tutorials/how-to-use-rsync-to-sync-local-and-remote-directories) your local codebase to remote. A couple of lines of bash

```
#!/usr/bin/env bash

cd ~/Documents
rsync -av proj/ root@server:~/a-folder --delete --exclude=exclude-folder/
```

And that's it.&#x20;

**Tip**: Don't forget to forward your nrepl ports as well.

Although **this is very specific to Clojure** the **key idea is to use an additional dedicated system for your computation** and **make it seem like your local machine is the dedicated machine**.&#x20;

Skip upgrading to an expensive macbook and get a cheap server(take advantage of promo credits😬)&#x20;

## Links

* [IntelliJ IDEA](https://www.jetbrains.com/idea/)
* [Ring Clojure](https://github.com/ring-clojure/ring)
* [Figwheel](https://github.com/bhauman/lein-figwheel)
* [Brave browser](https://brave.com/)
* [Linode Pricing](https://www.linode.com/pricing/)
* [SSH port forwarding](https://www.ssh.com/ssh/tunneling/example)
* [File watchers—IntelliJ IDEA](https://www.jetbrains.com/help/idea/using-file-watchers.html#ws_creating_file_watchers)
* [Rsync local to remote](https://www.digitalocean.com/community/tutorials/how-to-use-rsync-to-sync-local-and-remote-directories)

&#x20;[![Cadjak](https://img.shields.io/badge/contact-me-feff02.svg?style=flat\&colorA=0a0a0a)](mailto:abhinav@devarkm.com?subject=Hey%20I've%20found%20you%20through%20your%20docs\&body=I%20would%20like%20to%20talk%20about) [![CM](https://img.shields.io/badge/connect--with-me-feff02.svg?style=flat\&colorA=0a0a0a)](https://www.linkedin.com/in/abhinavrm/)
