How does the transaction (undo/redo) system work?

I would like the transaction system to handle the create/update/deletion of some custom objects.

Then I can proceed as follow:

// Create custom object:
GEditor->BeginTransaction(FText::FromString("Create object"));

UCustomObject* CustomObject = NewObject<UCustomObject>(this, TEXT("CustomObject1"));
CustomObject->Modify();
CustomObject->AnotherCustomUObject = NewObject<UAnotherCustomObject>(this, TEXT("AnotherCustomObject1"));
// Should I call CustomObject->AnotherCustomUObject->Modify() ?
CustomObject->AnotherCustomUObject->AUProperty++;

GEditor->EndTransaction();

// Modify custom object:
GEditor->BeginTransaction(FText::FromString("Modify object"));

CustomObject->Modify();
// Should I call CustomObject->AnotherCustomUObject->Modify() ?
CustomObject->AnotherCustomUObject->AUProperty++;

GEditor->EndTransaction();

 // Delete custom object:
GEditor->BeginTransaction(FText::FromString("Modify object"));

// Should I call CustomObject->Modify() ?
// Should I call CustomObject->AnotherCustomUObject->Modify() ?
CustomObject->ConditionalBeginDestroy();
CustomObject = nullptr;

GEditor->EndTransaction();

Will all objects (and subobjects or subUproperties) correctly be recreated/updated/deleted on the first/second/third undo (and redo correctly handled)?

As far as I understood, those custom objects must necessarily be UObjects (with UProperties). How big is an UObject compare to a plain object? Could this affect performances? I will created hundreds of thousands UObjects (vertices of a mesh) in some transactions, is it a problem?

I already created a parallel undo/redo system with plain c++ objects which sync with the Unreal Editor transaction system, it works well ; the only thing is that the UE transaction manager does not know how big (in terms of memory) are my objects.