I will try to give the most practical answer, the reality of "is this converged" is that you cannot know without checking by going past it. You say that you would like to save time doing these calculations, but the worst loss of time is sometimes the loss of your own human time as you get confusing results later.
I am unsure how you came to the number of 4 (cell vector * kpts?), but lets see using GPAW if that makes sense. I am using what are likely unconverged settings with an unrelaxed structure. Even then, lets see if we see a convergence on a (12, 12, X) kpoint set.

As you can see, there is something strange going on around 6 or 7 kpts in the z direction but otherwise looks converged at 4. Tightening my settings might remove that strange bump. If I saw this and could not correct it, I would probably choose to run initial optimizations at (12, 12, 4) and final optimizations at (12, 12, 8).
I strongly recommend you do the same and check what you see. If you are unsure what convergence looks like you could provide us with a similar graph. If you have a property of the system you are investigating, use that as well as total energy.
GPAW version 20.1.0 and ASE version 3.19.2 were used to generate this data. Here is the script I used.
from ase.build import bulk
from ase.visualize import view
from gpaw import GPAW, PW
import matplotlib.pyplot as plt
from matplotlib.colors import LogNorm
import numpy as np
a = 1.42
c = 6.70
kpt_min = 1
kpt_max = 16
atoms = bulk("C", crystalstructure="hcp", a=a, c=c)
x = np.arange(kpt_min, kpt_max)
e = np.zeros((kpt_max-kpt_min))
for index, kpt in enumerate(x):
calc = GPAW(mode=PW(350), kpts=(12, 12, kpt), occupations={'name': 'fermi-dirac', 'width': 0.05})
atoms.calc = calc
e[index] = atoms.get_potential_energy()
plt.plot(x, e, linestyle="-", marker="o")
plt.show()