Assuming it’s multiplayer then you likely need an instance per buff on the server to tick them correctly. But what you send to the client can always be at least partially collapsed if not completely.
What you will find is that if you make the system data driven you will wind up with almost no logic specific to a single buff/debuff. So I normally go with something like an Effect and EffectType. I actually use that for anything that can happen in combat. Damage, damage over time, buffs, debufs, are all effects of various types. The types I categorize by the mechanic, not what you call them in game.
For instance here a partial list of effects from my game.
DirectDamage,
DamageOverTime,
DirectHealing,
HealingOverTime,
DamageTakenIncrease,
DamageTakenDecrease,
DamageDecrease,
HealingTakenDecrease,
HealingIncrease,
HealingDecrease,
SpeedIncrease,
SpeedDecrease,
CriticalIncrease,
CriticalDecrease,
PhysicalResistIncrease,
PhysicalResistDecrease,
DamageReflect
DamageOverTime/HealingOverTime for example is actually a bug. I still had it in my list and put it here to illustrate how not to do it. Healing over time should be though of as DirectHealing with a certain duration/number of ticks.
So the hard part here is identifying the base mechanics.
So what you will end up with is a system that is ticking all effects using a single global timer. One second is usually the simplest. From there I would probably then have systems designed around the various base effect mechanics. Like your tick system marks an effect as this effect should fire. And then your other systems that handle mechanic specific logic filter by is the effect marked as should tick, and is it an effect type that system deals with. So kind of like a pipeline flow.
You could just start with one system and then expand as you grow, that is most likely what I would do starting out. Single system that abstracts out the handling into methods which can later move to systems of their own.
Stacking should be abstracted out. It’s potentially the most complex part of all this and it should be handled uniformly over all effects. That’s not to say you can’t have multiple stacking types. But make them effect specific and be prepared for some pain down the road.