Alright, imagine you want to start a “vanilla” Minecraft server with your 4-7 pals. You have $15 in pocket money now, and you are willing to spend US$10-15 per month. Let us get into it.
There are a variety of hosts out there, all of which have distinct pros and cons. I personally recommend PebbleHost, since they have a reasonable selection of options for low-medium range Minecraft servers.
You have two options if you want a playable 18.5+ TPS experience, Premium and Extreme. Extreme allows you to change Java startup flags (Aikar’s Flags), and grants you Dedicated CPU threads. I will be using Premium, since the difference isn’t that dramatic.
For some reason, most hosts would have you assume that RAM is the most valuable resource when running a Minecraft server. This is only partially true. A faster CPU means you will use less of your memory, since the Java GC will function more efficient. Since I will be targeting version 1.16.4/5, I am going to be purchasing 5GB. For NA markets, this costs you US$11.25/mo. You can also upgrade to 6GB, which will run you US$13.50/mo.
Simply click “Yes.”
Simply click “Disabled (Unprotected).”There are a couple of other “Addons” you can purchase, but in my opinion, these are all just a waste of money when you can set it up yourself. 
You are ready to hit that big ol’ buy button. 
Great, now we have a server on PebbleHost that we are ready to work with. 
You do not need to buy a domain, but it will make you look a lot more professional, as well as making it easier for your players to connect. While PebbleHost offers a free “subdomain”, it reeks of crappy sites like Aternos and Minehut and I do not recommend you use it.
On registrars like Namecheap, domains are dirt cheap.
.xyz TLD domains go for US$1/yr. Hmm, wonder why this site is regulad.xyz.

.Keep this tab open, you will need it soon.
Cloudflare is one of the best ways to manage a domain, regardless of which registrar you are using.

There are two things you can do here, you can either directly connect the domain to the server with only DNS, or you can use a proxy service like TCPShield.
If you are just using DNS, you only need to make an A record and an SRV record.

123.123.123.123, then make an A record like this: A @ 123.123.123.123 3600 
25566, then make an SRV record like this: SRV _minecraft._tcp.example.com 0 0 25566 example.com (with example.com being your domain, of course) 
PebbleHost also has a guide on this.
Only use TCPShield if you are not using Geyser: Geyser tends to break when using another proxy. For only 4-7 players, there is no need for anything but the free plan.


CNAME record. 
CNAME record on Cloudflare. 

All done!
Ok, you have a server, you (might) have a domain that connects to the server, and you are ready to get into the more setup-y bits.
You’ll need 3 essential tools; you will use these to edit & pull files on the server. Install these if you do not already use them.
You should have information on hand, you will be using this a lot.
You should setup your tools before you need them. Notice: These instructions are for Windows machines. You are on your own for macOS, but if you need help on Linux, drop me a line.
.txt file and open properties.
* If you do not see NP++, you should scroll down to “Look for another app on this PC,” then locate the NP++ executable, normally in “Program Files” or “Program Files (x86).” .txt file you open will open in NP++ instead of Notepad.

1. PebbleHost FTP Address, (normally looks like na000.pebblehiost.com) goes into the “Host name:” field. 2. 21 goes into the “Port number:” field. 3. PebbleHost Panel Email and PebbleHost Server ID goes into the “User name:” field. (normally looks like {email}.{serverid}) 4. PebbleHost Panel Password goes into the “Password:” field.Alright, your server is up, your tools are installed and setup, and we are ready to get to work.
Minecraft Java Edition Server is a very resource intensive program, so we must optimize it heavily to have a good experience.
Note: These steps apply to almost any Minecraft host that lets you change your server JAR. If your host does not: why aren’t you using PebbleHost?
Yatopia is a collection of patches from many different paper forks. While it is not the most stable, it’s still very efficient. No other fork is even close. I use it myself.
You can download it from their CI.
At the time of writing, the most stable build is #1. The filename is yatopia-1.16.5-paperclip-b1.jar. This will (of course) change with time, so expect it to be just a little different.

Luckily, someone else has already done the heavy lifting here. Check out this SpigotMC thread for most important information.
PebbleHost has some more options for its loader. Just copy the text below into your pebblehost.yml:
# Version 1.3.6
# This is the settings file for the PebbleHost server loader.
# Got a suggestion for this file? Join our discord and suggest it using -suggest
# THESE SETTINGS CAN BREAK PARTS OF YOUR SERVER, BE CAREFUL WHEN EDITING THEM
# If you break this file, Please delete it and it will automatically regenerate.
### Automatic reboot / restart on crash settings
#
# Possible Settings: true, false
# Default: false
#
# This will enable and create a start.sh file which is required for both using the /restart commnad
# and is required for a server to restart if it crashes.
# Please ensure your server supports this file format and it is setup within spigot.yml
#
auto-reboot=true
### Server URL redirection
#
# This setting allows you to redirect any URL requests to your servers IP to your own website
# For example, if your servers IP is 1.25.6.54:25567 you can redirect 1.25.6.54 in your browser to your website
# You need a domain for this to work!
#
# Your servers IP Address (must be a domain!)
redirect-from=
# The website you would like users to be redirected to
redirect-to=
### Heaplimiter Settings
#
# If your server is running out of metaspace memory frequently we suggest enabling this option, You may read more @ https://help.pebblehost.com/en/article/1lsc8ad/
#
# Possible Settings: 1,2,3
# Default: 1
# 1. 0MB
# 2. 300MB
# 3. 600MB
heaplimited=3
### Startup flag options
#
# The following option enables UTF-8 encoding in your servers startup settings
#
# Possible Settings: true, false
# Default: false
#
utf8=false
# This option removes the 20 second wait time by adding the -DIKnowWhatImDoingISwear flag to your servers startup command
#
# Possible Settings: true, false
# Default: false
#
waitremoval=false
# This option adds the --forceUpgrade argument to your servers startup for 1 boot allowing you to upgrade to a new version.
#
# Possible Settings: true, false
# Default: false
#
forceupgrade=false
### Forge Timeout Settings
#
# You can set the following options inside the `-Dfml.readTimeout=` flag on your server
#
# Possible Settings: 1,2,3
# Default: 1
# 1. Disabled
# 2. 120 seconds
# 3. 240 seconds
forgetimeout=1
### Rescue Mode
#
# This enables a temporary 1.8 paper server to test / debug any issues.
rescue=false
### Java Version setting
# Possible Settings: 8,11
# Default: 8
# 8. Your server will run on Java 8.
# 11. Your server will run on Java 11.
javaversion=11
### Reverse Proxy Settings
#
# Please configure these options from within your panel under Tools -> Reverse Proxy
# Reverse Proxy Domain
proxy-domain=
# Reverse Proxy Port
proxy-port=
#
# Please keep in mind, Any changes made to this will take up to 60 seconds to update and will require a server reboot.
I have another guide on installing plugins: look here.