World#updateEntities() runs every tick and iterates through the entire tickableTileEntitiesList and calls their update() method. So the update() method should be called EVERY tick for any ITickable tile entity (provided it is in the tickableTileEntitiesList).
To get on the tickableTileEntitiesList, that happens in the World#addTileEntity() method so long as it is in the loadedTileEntityList and also instanceof ITickable.
I suppose it is possilble that there is some cases where the loadedTileEntity list isn't updated by the time the addTileEntity() method is called. The updateEntities() method goes through these general steps in this exact order:
1. Iterates through tileEntitiesToBeRemovedList and runs onChunkUnload() method, removes them from the tickableTileEntitiesList and then removes them from the loadedTileEntitiesList.
2. Iterates through tickableTileEntitiesList and if the tile entity is valid and hasWorld() are true, checks that the block in that position is loaded and inside the world border. If the tile entity is invalid it is removed from the loadeTileEntitiesList and also from the chunk's tile entity association to that BlockPos. Interestingly it is not removed from the tickableTileEntitiesList at this time.
3. Iterates through the addedTileEntitiesList. I find it interesting that it does the adding at the end, but probably an attempt to make sure all these lists are in sync. But it means that there is one tick between adding the tile entity and the first time it is ticked. Basically the tile entity is checked to be valid and then added to the loadedTileEntitiesList. Then it separately checks if the block is loaded and associates it to the chunk's block position including calling a notifyBlockUpdate().
Basically, there are a lot of things that need to be synced and in common Minecraft fashion the coding isn't super organized leaving suspicion related to logical holes. In fact there are comments already in this code such as: //Forge: Bugfix: If we set the tile entity it immediately sets it in the chunk, so we could be desynced
That's about all the effort I'm interested in putting into investigating at this time, but hopefully gives you some ideas on how to debug. I would use the debugger and set breakpoints throughout the World#UpdateEntities() method and watch the order in which your tile entity is added to each list, and when it gets the update() calls.
However, my main point is that the intention seems to be that within one tick from a block with tile entity being added, it should be on the loadedTileEntitiesList and if it is also ITickable should run update() every tick from then on. If yours is not, then it is a bug somewhere.